1. 程式人生 > >2.3 序列程式設計-表示式求值

2.3 序列程式設計-表示式求值

表示式具備與模式相同的語法,同時表示式還可以包含函式呼叫或傳統的中序算術表示式。函式呼叫的寫法很傳統,如:area:triangle(A, B, C)便代表以引數ABC呼叫函式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/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

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

使用apply對BIF進行求值時,可以使用erlang作為模組名。

腳註

[4] 假設所有函式呼叫都結束。
[5] 即是說函式的與呼叫上下文無關。