Erlang 01

杜禄
2023-12-01
 
2006/9/8

分布式、并行计算语言Erlang 学习笔记(第一部分)

Erlang是由爱立信公司开发的一种平台式语言,可以说是一种自带了操作系统平台的编程语言,而且在这个平台上实现了并发机制、进程调度、内存管理、分布式计算、网络通讯等功能,这些功能都是完全独立于用户的操作系统的,它采用的是类似于Java一样的虚拟机的方式来实现对操作系统的独立性的。

介绍一下Erlang先:

1、并发性:Erlang的轻量级进程可以支持极高的并发性,而且在高并发的情况下内存使用相当的少。Erlang的并发性并不会受到宿主操作系统并发性的限制。

2、分布式:最开始Erlang的设计目标就是实现分布式环境,一个Erlang的虚拟机就是一个Erlang网络上的节点。一个Erlang节点可以在另一个Erlang节点上创建自己的并发进程,而子进程所在的节点可能是运行其他的操作系统的服务器。不同节点的之间的可以进行极为高效而又精确的通信,就像它们运行在同一个节点一样。

3、鲁棒形:Erlang内部建设有多种错误检测原语。我们可以通过这些原语来架设高容错性的系统。例如,一个进程可以监视其他进程的状态和活动,即使那些被监控的进程处于其他节点。在分布式状态下,我们可以把系统配置成具有Fail-over功能的分布式系统。当有其他节点出错的时候,系统会把他的运行场景自动快速的切换备份节点上。Erlang支持9个9的级别的故障率,一年只有几分钟的故障时间。

4、软实时:Erlang是一个“软”实时系统(Soft Real Time),它可以提供毫秒级别的响应。

一般的情况下,使用Erlang系统可以比其他系统的并发能力(例如Web会话负载)放大20~30倍。

下面我们就从Erlang的基础开始:

第一部分:Sequential Programming 顺序化编程

目录
--------------------------------------------------------------------------------

Numbers. 
    ——Integers 整型
    ——Floats 浮点型
Atoms 字符串
Tuples 复表
Lists 链表
Variables 变量
Complex Data Structures 复杂数据结构
Pattern Matching 匹配赋值
Function Calls 函数调用
The Module Systems 模块系统
Starting the system 启动系统
Built in Functions (BIFs) 内建函数
Function syntax 函数语法
An example of function evaluation 一个例子
    ——Guarded function clauses 条件子句
Examples of Guards 使用条件判断的例子
Traversing Lists 操作链表
Lists and Accumulators 链表和聚集器
Shell commands Shell命令
Special Functions 特殊函数
Special Forms 特殊形式

--------------------------------------------------------------------------------

Numbers
Integers
10
-234
16#AB10F
2#110111010
$A

Floats
17.368
-56.654
12.34E-10.

B#Val is used to store numbers in base < B >.
B#Val:Val是用B进制表示的。
$Char is used for ascii values (example $A instead of 65).
$Char的值为Char代表的ASCII代码值,例如$A等于65。

--------------------------------------------------------------------------------

Atoms
abcef
start_with_a_lower_case_letter
'Blanks can be quoted'
'Anything inside quotes /n/012'

Indefinite length atoms are allowed.
系统允许无限长度的字符串。
Any character code is allowed within an atom.
在字符串中允许加入ASCII码代表的数字,只不过需要转义一下 :)

--------------------------------------------------------------------------------

Tuples
{123, bcd}
{123, def, abc}
{person, 'Joe', 'Armstrong'}
{abc, {def, 123}, jkl}
{}

Used to store a fixed number of items.
可以用来存储定长的项。
Tuples of any size are allowed.
对一个复表来说。可以是任意长度的,只不过定下来长度后不能更改而已。

--------------------------------------------------------------------------------

Lists
[123, xyz]
[123, def, abc]
[{person, 'Joe', 'Armstrong'},
  {person, 'Robert', 'Virding'},
  {person, 'Mike', 'Williams'}
]
"abcdefghi"
        becomes - [97,98,99,100,101,102,103,104,105]
""
        becomes - []

Used to store a variable number of items.
用来存储不定长的项。
Lists are dynamically sized.
允许动态改变链表的长度。
"..." is short for the list of integers representing the ascii character codes of the enclosed within the quotes.
使用""包括起来的字符串将被转换为对应的ASCII码。

--------------------------------------------------------------------------------

Variables
Abc
A_long_variable_name
AnObjectOrientatedVariableName

Start with an Upper Case Letter.
以大写字母开始。
No "funny characters".
不允许一些奇怪的字符出现。
Variables are used to store values of data structures.
变量是用来存储数据结构内容的。
Variables can only be bound once! The value of a variable can never be changed once it has been set (bound).
变量只能被绑定一次,一旦绑定完成后,不允许修改原绑定关系。

--------------------------------------------------------------------------------

Complex Data Structures
[{{person,'Joe', 'Armstrong'},
       {telephoneNumber, [3,5,9,7]},
       {shoeSize, 42},
       {pets, [{cat, tubby},{cat, tiger}]},
       {children,[{thomas, 5},{claire,1}]}},
  {{person,'Mike','Williams'},
       {shoeSize,41},
       {likes,[boats, beer]},
...

Arbitrary complex structures can be created.
可以创建任意复杂的数据结构。
Data structures are created by writing them down (no explicit memory alloca- tion or deallocation is needed etc.).
数据结构的定义很简单,只需要写下来就可以了,不用关心显式的分配和删除内存区域。
Data structures may contain bound variables.
数据的结构中允许使用变量。

--------------------------------------------------------------------------------

Pattern Matching
A = 10
Succeeds - binds A to 10
操作成功,A被绑定为10

{B, C, D} = {10, foo, bar}
Succeeds - binds B to 10, C to foo and D to bar
操作成功,B被绑定为10,C为foo,D为bar

{A, A, B} = {abc, abc, foo}
Succeeds - binds A to abc, B to foo
操作成功,A为abc,B为foo

{A, A, B} = {abc, def, 123}
Fails
操作失败

[A,B,C] = [1,2,3]
Succeeds - binds A to 1, B to 2, C to 3
操作成功,A为1,B为2,C为3

[A,B,C,D] = [1,2,3]
Fails
操作失败

--------------------------------------------------------------------------------

Pattern Matching (Cont)
[A,B|C] = [1,2,3,4,5,6,7]
Succeeds - binds A = 1, B = 2,C = [3,4,5,6,7]
操作成功,A为1,B为2,C为[3,4,5,6,7]

[H|T] = [1,2,3,4]
Succeeds - binds H = 1, T = [2,3,4]
操作成功,H为1,T为[2,3,4]

[H|T] = [abc]
Succeeds - binds H = abc, T = []
操作成功,H为abc,T为[]

[H|T] = []
Fails
操作失败

{A,_, [B|_],{B}} = {abc,23,[22,x],{22}}
Succeeds - binds A = abc, B = 22
操作成功,A为abc,B为22

Note the use of "_", the anonymous (don't care) variable.
注意:"_"为匿名变量

--------------------------------------------------------------------------------

Function Calls
module:func(Arg1, Arg2, ... Argn)
func(Arg1, Arg2, .. Argn)

Arg1 .. Argn are any Erlang data structures.
Arg1到Argn可以是任意的Erlang的合法数据类型。
The function and module names (func and module in the above) must be atoms.
函数名和模块名必须是字符串。
A function can have zero arguments. (e.g. date() - returns the current date).
函数允许不带参数。例如date()返回当前的日期。
Functions are defined within Modules.
函数应在模块内被定义。
Functions must be exported before they can be called from outside the module where they are defined.
在定义该函数的模块外调用该函数之前,必须首先在外声明该函数(export)。

--------------------------------------------------------------------------------

Module System
-module(demo).
-export([double/1]).
double(X) ->
times(X, 2).
times(X, N) ->
X * N.

double can be called from outside the module, times is local to the module.
double函数可以在模块外进行调用,times函数位于该模块内。
double/1 means the function double with one argument (Note that double/1 and double/2 are two different functions).
double/1意味着该函数带有一个参数的形式,如果是double/2,则代表这带有两个参数的double函数原型。

--------------------------------------------------------------------------------

Starting the system
unix> erl
Eshell V2.0
1> c(demo).
double/1 times/2 module_info/0
compilation_succeeded
2> demo:double(25).
50
3> demo:times(4,3).
** undefined function:demo:times[4,3] **
** exited: {undef,{demo,times,[4,3]}} **
4> 10 + 25.
35
5>

c(File) compiles the file File.erl.
c(File)意味着编译文件File.erl
1> , 2> ... are the shell prompts.
1> , 2> ...是提示符而已~~
The shell sits in a read-eval-print loop.
Shell忠实的进行着读取命令->执行->输出结果的循环。

--------------------------------------------------------------------------------

Built In Functions (BIFs)
date()
time()
length([1,2,3,4,5])
size({a,b,c})
atom_to_list(an_atom)
list_to_tuple([1,2,3,4])
integer_to_list(2234)
tuple_to_list({})

Are in the module erlang.
内建函数是默认的Erlang模块中的。
Do what you cannot do (or is difficult to do) in Erlang.
它们负责做哪些我们很难或者不能够在Erlang中做到的事情。
Modify the behaviour of the system.
用于修改系统的行为模式。
Described in the BIFs manual.
可以参考内建函数的手册。

--------------------------------------------------------------------------------

Function Syntax
Is defined as a collection of clauses.
它们由一系列的字句所定义。
func(Pattern1, Pattern2, ...) ->
... ;
func(Pattern1, Pattern2, ...) ->
... ;
...
func(Pattern1, Pattern2, ...) ->
... .

Evaluation Rules
执行规则
Clauses are scanned sequentially until a match is found.
子句被顺序的扫描,直到找到匹配的为止。
When a match is found all variables occurring in the head become bound.
当一个匹配成功时,所有的形式变量就被绑定。
Variables are local to each clause, and are allocated and deallocated automatically.
变量存在于函数的生存周期内,它的内存的分配和销毁都是自动实现的。
The body is evaluated sequentially.
函数体的执行是顺序的。

--------------------------------------------------------------------------------

Functions (cont)
-module(mathStuff).
-export([factorial/1, area/1]).
factorial(0) -> 1;
factorial(N) -> N * factorial(N-1).

area({square, Side}) ->
       Side * Side;
area({circle, Radius}) ->
       % almost :-)
       3 * Radius * Radius;
area({triangle, A, B, C}) ->
       S = (A + B + C)/2,
       math:sqrt(S*(S-A)*(S-B)*(S-C));
area(Other) ->
       {invalid_object, Other}.

--------------------------------------------------------------------------------

Evaluation example
factorial(0) -> 1;
factorial(N) ->
N * factorial(N-1)

> factorial(3)
matches N = 3 in clause 2
== 3 * factorial(3 - 1)
== 3 * factorial(2)
matches N =2 in clause 2
== 3 * 2 * factorial(2 - 1)
== 3 * 2 * factorial(1)
matches N = 1 in clause 2
== 3 * 2 * 1 * factorial(1 - 1)
== 3 * 2 * 1 ? factorial(0)
== 3 * 2 * 1 ? 1 (clause 1)
== 6

Variables are local to each clause.
Variables are allocated and deallocated automatically.
变量存在于函数的生存周期内,它的内存的分配和销毁都是自动实现的。

--------------------------------------------------------------------------------

Guarded Function Clauses
factorial(0) -> 1;
factorial(N) when N > 0 ->
         N * factorial(N - 1).

The reserved word when introduces a guard.
关键字when引入了一个条件。
Fully guarded clauses can be re-ordered.
完善的条件判断可以把代码重排列而不出错。
factorial(N) when N > 0 ->
         N * factorial(N - 1);
factorial(0) -> 1.

This is NOT the same as:
不等同于一下的代码:
factorial(N) ->
      N * factorial(N - 1);
factorial(0) -> 1.

(incorrect!!)
这是不正确的!

--------------------------------------------------------------------------------

Examples of Guards
number(X) - X is a number X是一个实数
integer(X) - X is an integer X是一个整型
float(X) - X is a float X是一个浮点型
atom(X) - X is an atom X是一个字符串
tuple(X) - X is a tuple X是一个复表
list(X) - X is a list X是一个链表
length(X) == 3 - X is a list of length 3 X是一个长度为3的链表
size(X) == 2 - X is a tuple of size 2. X是一个大小为2的复表
X > Y + Z - X is > Y + Z X大于Y+Z
X == Y - X is equal to Y X等于Y
X =:= Y - X is exactly equal to Y X精确的等于Y
(i.e. 1 == 1.0 succeeds but
1 =:= 1.0 fails)
注意:1==1.0是正确的,但是1=:=1.0是不正确的,涉及精度问题。

All variables in a guard must be bound.
所有进行比较的变量必须经过绑定。

--------------------------------------------------------------------------------

Traversing Lists
average(X) -> sum(X) / len(X).
sum([H|T]) -> H + sum(T);
sum([]) -> 0.
len([_|T]) -> 1 + len(T);
len([]) -> 0.

Note the pattern of recursion is the same in both cases. This pattern is very common.
注意递归的写法,这是程序设计中很常见的。
Two other common patterns:
另外两种常见的样式为:
double([H|T]) -> [2*H|double(T)];
double([]) -> [].
member(H, [H|_]) -> true;
member(H, [_|T]) -> member(H, T);
member(_, []) -> false.

--------------------------------------------------------------------------------

Lists and Accumulators
average(X) -> average(X, 0, 0).
average([H|T], Length, Sum) ->
       average(T, Length + 1, Sum + H);
average([], Length, Sum) ->
       Sum / Length.

Only traverses the list ONCE
只需要操作该链表一次
Executes in constant space (tail recursive)
执行是原地进行的(尾部递归)
The variables Length and Sum play the role of accumulators
变量Length和Sum扮演着汇聚的角色
N.B. average([]) is not defined - (you cannot have the average of zero elements) -
evaluating average([]) would cause a run-time error - we discuss what happens when run time errors occur in the section on error handling .
注意:average([])是没有定义的(也就是说我们不能不带参数的调用该函数)——计算average([])将导致一个运行时错误,我们将在异常捕获中谈到。

--------------------------------------------------------------------------------

Shell Commands
h() - history . Print the last 20 commands.打印最后20条命令
b() - bindings. See all variable bindings.查看所有的变量绑定情况
f() - forget. Forget all variable bindings.清除所有的变量的绑定
f(Var) - forget. Forget the binding of variable 清除特定的变量的绑定
X. This can ONLY be used as a command to the shell - NOT in the body of a function!
只能在Shell环境下使用,不能在函数的函数体中使用!
e(n) - evaluate. Evaluate the n:th command in history.执行历史记录中的第n条命令
e(-1) - Evaluate the previous command. 执行上一条命令

Edit the command line as in Emacs
命令行的使用类似于Emacs的使用

--------------------------------------------------------------------------------

Special Functions
apply(Mod, Func, Args)

Apply the function Func in the module Mod to the arguments in the list Args.
将Func函数应用到Mod上,并带有参数Args。
Mod and Func must be atoms (or expressions which evaluate to atoms).
Mod和Func必须是字符串表示的(或者是表达式)
1> apply( lists1,min_max,[[4,1,7,3,9,10]]).
{1, 10}

Any Erlang expression can be used in the arguments to apply.
所有的Erlang表达式都可以用作Arg被使用。

--------------------------------------------------------------------------------

Special Forms
case lists:member(a, X) of
        true ->
                ... ;
        false ->
                ...
        end,
...
if
        integer(X) -> ... ;
        tuple(X) -> ...
end,
...

Not really needed - but useful.
虽然不是必须的,但是很有用就是了~~ 呵呵

 
 类似资料:

相关阅读

相关文章

相关问答