作者
Richard A. O'Keefe <ok(at)cs(dot)otago(dot)ac(dot)nz>
狀態
草案
類型
標準追蹤
建立於
2008-07-10
Erlang 版本
OTP_R12B-4

EEP 12:擴展列表解析式 #

摘要 #

新增元組值列表解析式,與列表和二元列表解析式搭配使用。

新增元組產生器,與列表和二元產生器搭配使用。

修正列表解析式限定詞中的語法錯誤,明確識別模式 = 值綁定,並以合理的方式處理它們。

規格 #

目前,Erlang 具有

'['  Expr '||' Generators-And-Tests ']'
'<<' Expr '||' Generators-And-Tests '>>'

用於產生列表和二進位資料,但沒有對應的元組產生形式。我們新增

'{' Expr '||' Generators-And-Tests '}'

其含義為 { E || G } 的行為與 erlang:list_to_tuple([E || G]) 相同,只是它不需要呼叫 erlang:list_to_tuple/1

目前,Erlang 列表解析式允許

Pattern '<-' Expr

用於枚舉列表,以及

Pattern '<=' Expr

用於枚舉二進位資料。我必須說,第二種形式不僅是自找麻煩,更是自尋死路。此提案新增三種新形式

Pattern '['  '<-' ']'  Expr
Pattern '{'  '<-' '}'  Expr
Pattern '<<' '<-' '>>' Expr

分別用於枚舉列表、元組和二進位資料,提供 Expr 應該是什麼的象徵性表示。 [<-]<< <- >> 與現有的 <-<= 具有完全相同的語意。Pattern {<=} Expr 的語意與 Pattern <- erlang:tuple_to_list(Expr) 相同,只是不需要呼叫 erlang:tuple_to_list/1

目前,「產生器與測試」部分允許一系列產生器和測試,其中測試是任何表達式。測試必須評估為 'false' 或 'true'。 Pattern = Expr 的形式在語法上是一個表達式,因此允許作為測試。然而,在上下文中,這毫無意義。對於給定的 Expr,有四種可能的結果

  1. Expr 引發例外 => 引發例外。
  2. Expr 不產生 false 或 true => 引發例外。
  3. Expr 產生 false => 測試失敗;這與沒有 Pattern 的 Expr 相同。
  4. Expr 產生 true => 測試成功;這與沒有 Pattern 的 Expr 相同,並且事先有 Pattern = true。

此提案更改了列表解析式的部分描述,使每個 Qualifier 要麼是產生器、綁定器或篩選器。

產生器是列表產生器、元組產生器或位元字串產生器。

列表產生器寫為

Pattern <- List_Expr

或寫為

Pattern [<-] List_Expr

其中 List_Expr 是一個表達式,其必須評估為一個 term 的列表。

元組產生器寫為

Pattern {<-} Tuple_Expr

其中 Tuple_Expr 是一個表達式,其必須評估為一個 term 的元組。

位元字串產生器寫為

Bit_String_Pattern <= Bit_String_Expr

或寫為

Bit_String_Pattern << <- >> Bit_String_Expr

其中 Bit_String_Expr 是一個表達式,其必須評估為一個位元字串。

產生器模式中的變數會遮蔽函數子句中列表解析式周圍的變數。這些變數在列表解析式外部不可見。

綁定器的形式為

Pattern = Expr

Pattern = Binder

這會評估 Expr 並將結果與 Pattern 匹配,綁定其中的變數。綁定器模式中的變數會遮蔽函數子句中列表解析式周圍的變數。這些變數在列表解析式外部不可見。

篩選器是一個評估為 'true' 或 'false' 的表達式。它們不限於成為防護測試。

動機 #

使用 Clean 以及 Erlang,缺少元組列表解析式和元組產生器令人感到惱火。在現有語言中可以獲得所需的效果,但特別是自從在語言中新增位元字串列表解析式以來,這種遺漏似乎完全沒有意義。新的形式比通過列表解析式的形式更容易思考和閱讀。

Haskell 列表解析式允許產生器、篩選器和 'let' 綁定。在 Erlang 列表解析式中缺少 let 綁定是很難理解的;事實上,看起來像是 Erlang 等效的 let 綁定被允許,但在執行時出現錯誤,這很難原諒。

原理 #

元組列表解析式的語法很明顯;沒有其他語法可以容忍。

元組產生器的語法具有某種笨拙的魅力;也許只有母親才會喜歡它。我嘗試過 <-[] <-{} <-«»,但很難讓 Yecc 喜歡它們。如果它能以某種方式擠過 Yecc 有限的前瞻,則箭頭在括號外的形式會更漂亮。對比

{ X+1 || X {<-} Xs }
{ X+1 || X <-{} Xs }

Erlang 目前允許在列表解析式限定詞中使用 Pattern = Expr,但賦予它完全無用的含義,這是一個需要緊急修正的語法錯誤。一種方法是識別嘗試使用此形式的情況,並將其報告為語法錯誤;對我來說,最好是實作它,使其按照預期的方式工作。

這三個擴展都可以通過對應到目前語言來實現

{ E || GT }  => erlang:list_to_tuple([E || GT])
P {<-} E     => P <- erlang:tuple_to_list(E)
P = E        => P <- [E]

參考實作正是這樣做的。然而,更好的實作是可能的,就像列表解析式的更好的實作一樣,並且同時至少代碼的效率不會低於程式設計師可以編寫的代碼,並且來源將更能揭示意圖。

向後相容性 #

新的列表解析式和產生器形式目前是語法錯誤,因此任何現有代碼都不會受到影響。

Erlang 編譯器目前允許新的綁定器形式(或更確切地說,是新修正的綁定器形式識別)。然而,如上所述,以其目前的閱讀方式來看,它不可能有用。可以想像,可能會有一些旨在引出錯誤的測試程式,一旦修復語法錯誤,這些程式將停止工作,但不太可能有任何實際程式碼受到影響。

參考實作 #

輔助檔案 eep-0012-1.diff 是要應用於 erl_parse.yrl 的修補程式檔案。修補後的檔案已通過 yecc 檢查,yecc 對此感到滿意。然而,這就是已完成的所有測試。

此實作完全在解析器中完成上一節中描述的三個來源到來源重寫。Erlang 系統的其餘部分無需任何變更。

版權 #

本文檔已放置在公共領域。