作者
James Hague <james(dot)hague(at)gmail(dot)com>
狀態
草案
類型
標準追蹤
建立於
2009年2月18日

EEP 27:多參數型別檢查 BIF #

摘要 #

型別檢查守衛(例如,is_float/1)在許多方面都很有用,但它們很冗長。我建議允許 is_ 系列函數使用多個參數,這可以顯著減少常見情況下的原始碼量。

規格 #

其中 is_type 代表任何 is_ 系列函數,例如 is_float

is_type(A, B, C, ...) 等同於 (is_type(A) andalso is_type(B) andalso is_type(C)...)

is_type 函數現在可以接受 1 到 N 個參數,其中 N 是實作定義的函數元數限制。

舊式守衛(例如,float/1)不會改變,因為其中一些函數兼具型別轉換的功能。

在 erlang 模組中直接引用這些函數僅適用於單一參數版本(例如 fun erlang:is_float/1)。

動機 #

我發現自己添加型別檢查守衛不僅是為了安全,也是為了提高程式碼產生的品質,尤其是在使用浮點數時。在 Erlang 中編寫具有 is_float 守衛的三或四元素向量數學函數是很冗長的。 is_float 檢查會使原本單行的函數因為加入多行守衛而變得龐大。

基本原理 #

以下是 Wings3D 專案中的一個範例

cross({V10,V11,V12}, {V20,V21,V22})
  when is_float(V10), is_float(V11), is_float(V12),
       is_float(V20), is_float(V21), is_float(V22) ->
    {V11*V22-V12*V21,V12*V20-V10*V22,V10*V21-V11*V20}.

is_float 檢查顯著提高了產生程式碼的品質,使浮點數可以保留在虛擬機器暫存器中,而不是在堆積上配置。如果允許 is_float 使用多個參數,則此程式碼可以重寫為

cross({V10,V11,V12}, {V20,V21,V22})
  when is_float(V10,V11,V12,V20,V21,V22) ->
    {V11*V22-V12*V21,V12*V20-V10*V22,V10*V21-V11*V20}.

在第二個版本中,意圖一目了然,而且加入型別檢查的原始碼權重不會壓倒函數。

多年來,Erlang 系統越來越依賴型別檢查。有 dialyzer 和 typer 工具。編譯器可以靜態推斷型別,並因此產生更好的程式碼。使型別檢查守衛在原始碼層級更輕巧,鼓勵它們的使用,並且更符合語言的整體語法密度。

向後相容性 #

如果實作此提案,所有對 is_type/1 函數的使用仍然有效。直接引用 erlang:is_floaterlang:is_atom 等作為 funs 將仍然按照原先的意圖工作。

參考實作 #

無。

版權 #

本文檔已置於公有領域。