Erlang是一门函数式语言
1. 介绍
2. 几个简单例程
3. Basic Principle
4. 并发编程
5. 分布式
6. 错误处理
7. 程序的健壮性
8. 附录(一些来自网络的小资料)
1. 介绍
Erlang是一门函数式语言。
Erlang是一个丹麦的数学家,他搞出来的一个概率分布Erlan分布,并且用这个分布开创一们学
科排队理论,电信上经常用这个分布来测算话务量,因此在电信界比较有名.当年Joe Amstrong把他
的语言命名为Erlang也是为了纪念这个为电信领域作出过卓越贡献的人.
Erlang是Ericsson和Ellemtel Computer Scientce Laboratories为解决电信领域中的并发和
分布式问题,设计的语言;从理论应用于实践的角度讲,主要探索的是函数式语言能否应用到通信
领域的大型交换机上,从Erlang的实践效果来看,答案是肯定的。
Erlang的优点:
(1) Code Loading Primitives允许在系统运行过程中升级代码。
(2) Erlang的轻量级进程可以支持极高的并发性,而且在高并发的情况下内存使用相当的少。
Erlang的并发性并不会受到宿主操作系统并发性的限制。Erlang的原子操
作是一个压栈级别的,而C语言是指令级别的。
(3) 最开始Erlang的设计目标就是实现分布式环境,一个Erlang的虚拟机就是一个Erlang网络上
的节点。一个Erlang节点可以在另一个-Erlang节点上创建自己的并发进程,而子进程所在的
节点可能是运行其他的操作系统的服务器。不同节点的之间的可以进行极为高效而又精确的通
信,就像它们运行-在同一个节点一样。
(4) Erlang内部建设有多种错误检测原语。我们可以通过这些原语来架设高容错性的系统。例如,
一个进程可以监视其他进程的状态和活动,即使那些被监-控的进程处于其他节点。在分布式状
态下,我们可以把系统配置成具有Fail-over功能的分布式系统。当有其他节点出错的时候,系
统会把他的运行场景自动快速-的切换备份节点上。
(5) Erlang是一个“软”实时系统(Soft Real Time),它可以提供毫秒级别的响应。
2. 几个简单例程
2.1 How to run?
笔者用的是Win2000。
首先安装otp_win32_R11B-2.exe。
a. 建立Erlang程序(vi/Emacs/Notepad都可以的编辑器),文件名的格式是 *.erl。
读者可以暂时先在下面的程序中,Copy一份来做运行试验。
b. 进入终端,把路径定位到您的*.erl目录中
c. 启动Erlang程序
笔者的启动方式:”d:/Program Files/erl5.5.2/bin/erl.exe”
读者可以根据自己的路径,启动程序。
d. 编译程序
c(math.erl).
或者 c(math).
注意:结尾的.是不能省略的
e. 运行
math:fib(10).
f. Erlang的帮助
help().
2.2 简单例程
2.2.1 阶乘
-module(math). %定义模块名字
%也可以理解成为一个起到命名空间
%的作用
-export([fact/1]). %起到了头文件(*.h)的作用
%声明这个函数,供外部调用
fact(0) -> 1;
fact(N) -> N * fact(N-1).
这是一个算阶乘的程序。
% — 注释符号
具体执行 fact(0)还是fact(N),Erlang是模式匹配的,当前的N匹配
上哪个定义,就执行哪一个。
/1 — 说明这个函数接受一个参数。
-> — 定义函数的方式,请类比数学当中的映射。
2.2.2 定义更多的函数
-module(math).
-export([fact/1]).
-export([fib/1]).
fact(0) -> 1;
fact(N) -> N * fact(N-1).
fib(1) -> 1;
fib(2) -> 2;
fib(X) -> fib(X-1) + fib(X-2).
也可以这样:
-module(math).
-export([fact/1, fib/1]).
… …
如果你要定义成这个样子:
-module(math).
-export([fact/1]).
fact(0) -> 1;
fact(N) -> N * fact(N-1).
fib(1) -> 1;
fib(2) -> 2;
fib(X) -> fib(X-1) + fib(X-2).
那么fib(N)只能在math模块内部使用(fib是private的)。
注:下面的程序为了简单,只是写实现。
2.2.3 操作List
reverse(L) -> reverse(L, []). %1
reverse([H|T], Acc) -> %2
reverse(T, [H|Acc]); %3
reverse([], Acc) -> %4
Acc. %5
[]是list的符号
%1 使用了[],这起到了辅助量的作用。
%2 [H|T] 这种形式代表取list的头和余下的部分
H绑定了list的头(Head)
T绑定了list的余下部分(Tail)
%[] 空表
%2 + %3 代表一个子句(clause),用’;'来分隔子句
子句内部用’,’
标识结束用’.’
你也许可以编个大段的程序,来体会何时用’,’ , ‘;’ , ‘.’。
2.2.4 匹配更多的函数
-module(math3).
-export([area/1]).
area({square, Side}) ->
Side * Side;
area({rectangle, X, Y}) ->
X * Y;
area({circle, Radius}) ->
3.14159 * Radius * Radius;
area({triangle, A, B, C}) ->
S = (A + B + C)/2,
math:sqrt(S*(S-A)*(S-B)*(S-C)).
这是一个计算基本图形面积的例程。
S为一个临时量。
可以通过math3:({triangle, 3, 4, 5})计算三角形
通过math3:({circle, 5})计算圆
2.2.5 快速排序
-module(sort).
-export([sort/1]).
sort([]) -> [];
sort([Pivot|Rest]) ->
{Smaller, Bigger} = split(Pivot, Rest),
lists:append(sort(Smaller), [Pivot|sort(Bigger)]).
split(Pivot, L) ->
split(Pivot, L, [], []).
split(Pivot, [], Smaller, Bigger) ->
{Smaller, Bigger};
split(Pivot, [H|T], Smaller, Bigger) when H < Pivot ->
split(Pivot, T, [H|Smaller], Bigger);
split(Pivot, [H|T], Smaller, Bigger) when H >= Pivot ->
split(Pivot, T, Smaller, [H|Bigger]).
这个排序大家很熟悉吧,在这里就不介绍这个算法的原理了。
只是想就这个例程来发一些感慨。
这个程序很简洁,实现即原理。
入学从Lisp或其他函数式语言而不是C语言来教授计算机课程,
个人感觉更能让学生专注在算法的理解上;如果,用C写这个程序,要考虑很
多怎样交换的细节问题、变量定义等,尤其老师会说递归是个很耗资源
的调用方式,很容易堆栈溢出,很多因素让学生分心了、对实现怀疑了。
希望有能力改变一些东西的老师,去改变一些东西。
3. Basic Principle
3.1 Tuples
特点:确定数目的item。
用于创建复杂的数据结构。
符号是’{}’。
请读者看一下2.2.4的例程,我们可以这样调用它。
> Thing = {triangle, 6, 7, 8}.
{triangle, 6, 7, 8}
>math3:area(Thing).
20.3332
这里就把Thing绑定(bound)到了一个tuple上--{triangle, 6, 7, 8},请读者注意
这里的用词:”绑定(bound)”。我们在Erlang中是没有变量的概念的,所有用到的量都是
一次性赋值,即绑定。
继续我们的Tuple…
Thing是一个有4项的tuple。第一项是原子量triangle,剩下的三项是整型数6,7,8。
其他例子:
{a, 12, b}, {}, {1, 2, 3}, {a, b, c, d ,e}.
3.2 List
特点:存储不定数目的item。
符号是’[]‘
例子:
[], [a, b, 12], [22], [a, 'hello friend']
3.3 补充Data Types
3.2.1 Constant data types
-Numbers: 123, -789, 3.14159, 7.8e12, -1.2e-45.
分为整数和浮点数。
-Atoms: abc, ‘An atom with spaces’, monday,green,hello_world
3.2.2 Compound data types(复合型)
用于把不同类型的数据组织起来。
-Tuples
-Lists
3.4 一个复杂的数据结构
组合使用tuples 和 lists可以帮助我们创建复杂的数据结构。
X = {book, preface, acknowledgments, contents,
{chapters, [
{chapter, 1, 'An Erlang Tutorial'},
{chapter, 2, ...}
]
}},
用一个复杂的数据结构,把一本书表示了出来,美极了。
3.5 Pattern matching
处理匹配失败了怎么办?
-module(temp).
-export([convert/2]).
convert({fahrenheit, Temp}, celsius) ->
{celsius, 5 * (Temp – 32) / 9};
convert({celsius, Temp}, fahrenheit) ->
{farenheit, 32 + Temp * 9 / 5};
convert({reaumur, Temp}, celsius) ->
{celsius, 10 * Temp / 8};
convert({celsius, Temp}, reaumur) ->
{reaumur, 8 * Temp / 10};
convert({X, _}, Y) -> %匹配失败了
{cannot,convert,X,to,Y}. %处理匹配失败
运行:
> temp:convert({fahrenheit, 98.6}, celsius).
{celsius,37.0000}
> temp:convert({reaumur, 80}, celsius).
{celsius,100.000}
> temp:convert({reaumur, 80}, fahrenheit).
{cannot,convert,reaumur,to,fahrenheit}
程序中使用了一个下划线’_'来捕捉失败的情况,这个’_'的作用像是C中的default
它表示:这里有一个值,但这个值具体是什么我不关心。
注意这个东西一定要放到最好,这一点不像C中的default,Erlang有些地方不是很
智能,这也许是基于电信中的效率考虑吧。设想热恋中,你鼓足勇气要说”I love you”
之类的东西了,这时候,电信信息要升级、匹配什么的,总之是断了一下……这让你
觉得有什么先兆,胡思乱想… …“算了,不说了”….
效率就是一切,把一切都交给程序员吧。
3.6 ‘=’
> N = {12, banana}.
{12,banana}
> {A, B} = N.
{12,banana}
> A.
12
> B.
banana
看明白了吗?
4. 并发编程
Erlang是并行语言。
也就是说Erlang对并行的支持是语言级别的,不需要操作系统的支持。
‘spawn’启动一个过程(process),给一个process发消息,从一个process收消息。
‘spawn/3′启动一个process并返回一个标识(identifier),这个标识用于收、发
消息。
语法: Pid ! Msg
Example: Pid ! {a, 12}
Pid : identifier
! : 发消息标识
{a, 12} : 一条消息
所有参数在发消息之前都要计算(比较:Erlang中是懒惰求值的,但是在发消息的
时候,必须提前计算)。
Example: foo(12) ! math3:area({square, 5})
计算foo(12) 和 math3:area({square, 5}),但是两边的计算规则是未定义的。
〔
这一段翻译的不好,原文:
foo(12) ! math3:area({square, 5})
means evaluate the function foo(12) (this must yield a valid process
identifier) and evaluate math3:area({square, 5}) then send the result
(i.e. 25) as a message to the process. The order of evaluation of the
two sides of the send primitive is undefined.
〕
‘receive’原语,用于收消息。
语法:
receive
Message1 ->
… ;
Message2 ->
… ;
…
end
含意:定义一组收消息的模式语意,用于在收到消息后,当消息匹配上一条
MessageN,执行这个消息’->’后面的语句。
如果收到的消息,没有匹配上receive…end中定义的模式,这个收消息的过
程将挂起,等待处理下一条消息;未匹配的消息,将保存,等待后续处理。
Example:
{A, Msg}
A ———————————>B
Msg
A<———————————-B
An echo process
-module(echo).
-export([start/0, loop/0]).
start() ->
spawn(echo, loop, []).
loop() ->
receive
{From, Message} ->
From ! Message,
loop()
end.
运行:
Id = echo:start(),
Id ! {self(), hello}.
self()是个内建函数(BIF),返回该过程的identifier
分享到:
相关推荐
这是一本讲解Erlang编程语言的入门指南,内容通俗易懂,插图生动幽默,示例短小清晰,结构安排合理。书中从Erlang的基础知识讲起,融汇所有的基本概念和语法。 这是一本讲解Erlang编程语言的入门指南,内容通俗易懂...
Erlang是一种面向并发的、函数式编程语言,由瑞典电信设备制造商Ericsson开发,用于构建高可用性、分布式和实时系统。这个“erlang资源”包含两本PDF书籍——《Erlang并发编程》和《Erlang入门手册》,它们是深入...
### Erlang多核编程入门知识点总结 #### 一、Erlang多核编程背景与重要性 - **多核时代的来临**:随着技术的发展,单个芯片内部的时钟周期可触及部分越来越少,多核处理器成为了不可避免的趋势。这不仅影响着...
可能涵盖简单的进程通信示例、函数应用、错误处理和模块化编程等内容。实践中编写并运行Erlang代码是提升技能的关键步骤,因为它能帮助理解Erlang的运行机制和并发特性。 Erlang的 OTP(Open Telecom Platform)...
### Erlang编程语言基础知识 ...通过以上介绍,我们不仅了解了Erlang的基础概念及其优势,还学习了如何安装配置Erlang环境以及简单的Erlang编程方法。希望这些信息能够帮助初学者快速入门Erlang编程。
### 并发编程在Erlang中的应用 #### 标题和描述中的核心知识点解析 **并发编程在Erlang中的应用(Concurrent ...这些知识点不仅有助于初学者快速入门,也为高级用户提供了深入理解和应用Erlang的强大工具。
通过以上内容的介绍,我们可以看出,《Erlang程序设计》这本书不仅是一本技术手册,更是引导读者理解并掌握Erlang编程思想的重要指南。无论是初学者还是有经验的开发者,都能从中获得有价值的知识和启发。
元概述Meta是一种尝试简化由提供的Erlang的元编程的尝试。...快速入门示例要使用meta只需添加以下标头: -include_lib("meta/include/meta.hrl").然后,要将任何Erlang代码转换为“ quote”,请将其包装到meta:quote
- **Erlang Shell**:介绍了如何通过Erlang Shell进行简单的交互式编程。 - **模块和函数**:解释了Erlang中模块的概念以及如何定义和调用函数。 - **元子(Atoms)**:讨论了Erlang中的一种基本数据类型——原子...
### Erlang 入门知识点详解 #### 一、引言 ...通过上述内容的学习,读者不仅能够掌握 Erlang 的基本编程知识,还能深入了解其并发编程和错误处理机制,为开发高性能和高可靠性的应用程序打下坚实的基础。
- **读者背景假设**: 假设读者有一定的计算机基础和基本的编程知识,但不一定需要具备丰富的开发经验。 #### 1.2 顺序编程 - **Erlang Shell**: - **定义**: Erlang Shell 是一个交互式的命令行环境,允许用户...
**开发语言**:RabbitMQ 使用 Erlang 语言编写,Erlang 是一种面向并发的编程语言,非常适合构建高并发和容错性强的系统。 **AMQP**:这是一种开放的协议标准,用于实现消息队列之间的通信。AMQP 协议支持多种消息...
总结来说,这个压缩包提供了一个完整的RabbitMQ和Erlang的安装流程,以及一个Java Maven项目的示例,帮助开发者快速入门并实践RabbitMQ的消息队列功能。通过阅读和执行这些步骤,你可以深入了解RabbitMQ和Erlang在...
"otp_win64_22.2.exe" 是 Erlang OTP 的 Windows 64 位版本,是运行 RabbitMQ 所必需的,因为 RabbitMQ 是用 Erlang 编程语言开发的。"rabbitmq-server-3.8.1.exe" 是 RabbitMQ 服务器的 3.8.1 版本的安装程序,这是...