• 表达式求值
    • 函数求值
    • 求值顺序
    • 应用

    表达式求值

    表达式具备与模式相同的语法,同时表达式还可以包含函数调用或传统的中序算术表达式。函数调用的写法很传统,如: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作为模块名。