表达式求值

表达式具备与模式相同的语法,同时表达式还可以包含函数调用或传统的中序算术表达式。函数调用的写法很传统,如:area:triangle(A,B,C)便代表以参数ABC调用函数area:triangle

Erlang 表达式的求值机制如下。

对项式求值得到其本身:

  1. > 222.
  2. 222
  3. > abc.
  4. abc
  5. > 3.1415926.
  6. 3.14159
  7. > {a,12,[b,c|d]}.
  8. {a,12,[b,c|d]}
  9. > {{},[{}],{a,45,'hello world'}}.
  10. {{},[{}],{a,45,'hello world'}}

浮点数的输出格式可能与它们的输入格式不完全一致。当表达式与项式同构且表达式中的函数调用都已求值完毕时,表达式将被求值为项式。应用一个函数时其参数首先被求值。

求值过程可以被认为是一个将表达式归结为基础项式的函数:

  1. ε(X) when Constant(X)→X
  2. ε({t1,t2,...,tn})→{ε(t1),ε(t2),...,ε(tn)}
  3. ε([t1,t2,...,tn])→[ε(t1),ε(t2),...,ε(tn)]
  4. ε(functionName(t1,t2,...,tn)→
  5. APPLY(functionName,[ε(t1),ε(t2),...,ε(tn)])

其中APPLY表示一个将参数应用到函数的函数。

函数求值

函数调用的写法如以下实例所示:

  1. > length([a,b,c]).
  2. 3
  3. > lists:append([a,b], [1,2,3]).
  4. [a,b,1,2,3]
  5. > math:pi().
  6. 3.14159

带冒号形式的函数将在和模块相关的章节中解释。调用没有参数的函数必须加上一对空的小括号(以此与原子式相区别)。

求值顺序

函数参数的求值顺序是不确定的。例如,f({a},b(),g(a,h(b),{f,X}))表示一个函数调用。对函数f的调用有三个参数:{a}b()g(a,h(b),{f,X})。第一个参数是一个只包含一个原子项a的元组。第二个参数是一个函数调用b()。第三个参数是函数调用g(a,h(b),{f,X})。在对f/3求值时,对b/0g/3的求值顺序是不确定的,不过h(b)g/3被求值。对b()h(b)的求值顺序也是不确定的。

在对形如[f(a),g(b),h(k)]的表达式进行求值时,f(a)g(b)h(k)的求值顺序是不确定的。

如果f(a)g(b)h(k)的求值过程没有副作用(即不发送消息、不创建进程等等),则[f(a),g(b),h(k)]与求值顺序无关[4]。这种属性叫作引用透明性[5]

应用

BIF apply(Mod,Func,ArgList)apply({Mod,Func},ArgList)用于将模块Mod中的函数Func应用到参数列表ArgList

  1. > apply(dates, classify_day, [monday]).
  2. weekDay
  3. > apply(math, sqrt, [4]).
  4. 2.0
  5. > apply({erlang, atom_to_list}, [abc]).
  6. [97,98,99]

使用apply对BIF进行求值时,可以使用erlang作为模块名。