2.3 序列程式設計-表示式求值
表示式具備與模式相同的語法,同時表示式還可以包含函式呼叫或傳統的中序算術表示式。函式呼叫的寫法很傳統,如: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})
在對形如[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] | 即是說函式的值與呼叫上下文無關。 |