串行编程

程序1.1用于计算整数的阶乘:

程序1.1

  1. -module(math1).
  2. -export([factorial/1]).
  3.  
  4. factorial(0) -> 1;
  5. factorial(N) -> N * factorial(N - 1).

函数可以通过shell程序进行交互式求值。 Shell会提示输入一个表达式,并计算和输出用户输入的任意表达式,例如:

  1. > math1:factorial(6).
  2. 720
  3. > math1:factorial(25).
  4. 15511210043330985984000000

以上的“>”代表 shell 提示符,该行的其他部分是用户输入的表达式。之后的行是表达式的求值结果。

factorial 的代码如何被编译并加载至 Erlang 系统中是一个实现相关的问题。 [1]

在我们的例子中,factorial函数定义了两个子句:第一个子句描述了计算factorial(0)的规则,第二个是计算factorial(N)的规则。当使用某个参数对factorial进行求值时,两个子句按照它们在模块中出现的次序被依次扫描,直到其中一个与调用相匹配。当发现一个匹配子句时,符号->右边的表达式将被求值,求值之前函数定义式中的变量将被代入右侧的表达式。

所有的 Erlang 函数都从属于某一特定模块。最简单的模块包含一个模块声明、导出声明,以及该模块导出的各个函数的实现代码。导出的函数可以从模块外部被调用。其他函数只能在模块内部使用。

程序1.2是该规则的一个示例。

程序1.2

  1. -module(math2).
  2. -export([double/1]).
  3.  
  4. double(X) ->
  5. times(X, 2).
  6.  
  7. times(X, N) ->
  8. X * N.

函数double/1可在模块外被求值[2]times/2则只能在模块内部使用,如:

  1. > math2:double(10).
  2. 20
  3. > math2:times(5, 2).
  4. ** undefined function: math2:times(5,2) **

在程序1.2中模块声明-module(math2)定义了该模块的名称,导出属性-export([double/1])表示本模块向外部导出具备一个参数的函数double

函数调用可以嵌套:

  1. > math2:double(math2:double(2)).
  2. 8

Erlang 中的选择是通过模式匹配完成的。程序 1.3 给出一个示例:

程序1.3

  1. -module(math3).
  2. -export([area/1]).
  3.  
  4. area({square, Side}) ->
  5. Side * Side;
  6. area({rectangle, X, Y}) ->
  7. X * Y;
  8. area({circle, Radius}) ->
  9. 3.14159 * Radius * Radius;
  10. area({triangle, A, B, C}) ->
  11. S = (A + B + C)/2,
  12. math:sqrt(S*(S-A)*(S-B)*(S-C)).

如我们所期望的,对math3:area({triangle,3,4,5})得到6.0000math3:area({square,5})得到 25 。程序1.3 引入了几个新概念:

元组——用于替代复杂数据结构。我们可以用以下 shell 会话进行演示:

  1. > Thing = {triangle, 6, 7, 8}.{triangle, 6, 7, 8}> math3:area(Thing).20.3332

此处Thing被绑定到{triangle, 6, 7, 8}——我们将Thing称为尺寸为4的一个元组——它包含 4 个元素。第一个元素是原子式triangle,其余三个元素分别是整数6、7和8。

模式识别——用于在一个函数中进行子句选择。area/1被定义为包含4个子句。以math3:area({circle, 10})为例, 系统会尝试在area/1定义的子句中找出一个与{circle, 10}相符的匹配,之后将函数定义头部中出现的自由变量Radius绑定到调用中提供的值(在这个例子中是10)。

序列临时变量——这二者是在area/1定义的最后一个子句中出现的。最后一个子句的主体是由两条以逗号分隔的语句组成的序列;序列中的语句将依次求值。函数子句的值被定义为语句序列中的最后一个语句的值。在序列中的第一个语句中,我们引入了一个临时变量S