表达式求值
表达式具备与模式相同的语法,同时表达式还可以包含函数调用或传统的中序算术表达式。函数调用的写法很传统,如:area:triangle(A,B,C)便代表以参数A、B和C调用函数area:triangle。
Erlang 表达式的求值机制如下。
对项式求值得到其本身:
- > 222.
- 222
- > abc.
- abc
- > 3.1415926.
- 3.14159
- > {a,12,[b,c|d]}.
- {a,12,[b,c|d]}
- > {{},[{}],{a,45,'hello world'}}.
- {{},[{}],{a,45,'hello world'}}
浮点数的输出格式可能与它们的输入格式不完全一致。当表达式与项式同构且表达式中的函数调用都已求值完毕时,表达式将被求值为项式。应用一个函数时其参数首先被求值。
求值过程可以被认为是一个将表达式归结为基础项式的函数:
- ε(X) when Constant(X)→X
- ε({t1,t2,...,tn})→{ε(t1),ε(t2),...,ε(tn)}
- ε([t1,t2,...,tn])→[ε(t1),ε(t2),...,ε(tn)]
- ε(functionName(t1,t2,...,tn)→
- APPLY(functionName,[ε(t1),ε(t2),...,ε(tn)])
其中APPLY表示一个将参数应用到函数的函数。
函数求值
函数调用的写法如以下实例所示:
- > length([a,b,c]).
- 3
- > lists:append([a,b], [1,2,3]).
- [a,b,1,2,3]
- > math:pi().
- 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/0和g/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。
- > apply(dates, classify_day, [monday]).
- weekDay
- > apply(math, sqrt, [4]).
- 2.0
- > apply({erlang, atom_to_list}, [abc]).
- [97,98,99]
使用apply对BIF进行求值时,可以使用erlang作为模块名。