作者
Richard A. O'Keefe <ok(at)cs(dot)otago(dot)ac(dot)nz>
狀態
最終版本/R12B-4 已在 OTP R12B-4 版本中實作
類型
標準追蹤
建立日期
2008-08-08
Erlang 版本
OTP_R12B-4

EEP 23: 允許在 fun M:F/A 中使用變數 #

摘要 #

fun M:F/A 應允許 MF 和/或 A 為變數。

規格 #

目前 fun M:F/A 的形式要求 M 為原子、F 為原子,而 A 為非負整數。現在將其一般化,允許它們中的任何一個或全部為變數。

動機 #

現在不建議使用元組 {M,F,A} 來表示函式。然而,有時直到執行階段才能取得某些資訊。例如,行為的作者可能希望引用回呼模組中的 start/0 函式,但執行階段可能存在任意數量的回呼模組。

M:F(E1, ..., En) 形式的呼叫中,模組名稱和函式名稱可以是原子或變數,但它們在 fun M:F/A 中不能是變數,這是不合理的。

事實證明,fun M:F/A 目前的實作方式是呼叫 erlang:make_fun(M, F, A),因此已經存在根據執行階段資料建立此類函式的功能。所缺少的就是為其加上一些語法。

原理 #

這裡所彌補的差距是在實務中感受到的。請參閱 2008 年 9 月 Erlang 郵件清單中的一個討論串。此提案將現有的形式一般化,但不會超過現有的函式呼叫語法已經一般化的程度。

或許需要解釋的是此提案的限制。

首先,此擴展是從常數擴展到常數或變數,而不是任意表達式。這主要是為了避免混淆剖析器和人們。fun (E1):(E2)/(E3) 的效果可以透過撰寫 M = E1, F = E2, A = E3, fun M:F/A 來實現,因此不會損失表達能力。由於 Erlang 的 lambda 形式以 “fun (” 開頭,因此 fun (E1):... 將難以剖析,並且會讓人們非常困惑。

其次,此擴展僅適用於 fun M:F/A,而不適用於 fun F/A。這是因為沒有 erlang:make_fun/2 可供呼叫;fun F/A 的實作非常棘手,需要建立一個特殊用途的膠合函式。在許多情況下,可以使用 fun ?MODULE:F/A 來代替。

向後相容性 #

所有現有的 Erlang 程式碼在語義不變的情況下仍然可以接受。由於沒有新增函式或指令,因此使用新的剖析器產生的 BEAM 檔案可以在舊版本中運作。

參考實作 #

輔助檔案 eep-0023-1.diff 是一個要套用至 erl_parse.yrl 的修補程式檔案。修補後的檔案已由 yecc 檢查過,它對此感到滿意,並且產生的 .erl 檔案可以順利編譯。然而,這就是已完成的全部測試。

實作所做的全部工作是

  1. 接受 fun M:F/A,其中 MFA 是常數或變數,
  2. 產生過去在它們都是常數時所產生的相同抽象語法術語,
  3. 在至少有一個是變數時,假裝已撰寫 erlang:make_fun(M, F, A)。只有剖析器會參與其中。

版權 #

本文件已置於公共領域。