添加元组值推导式,使其与列表和二进制推导式相对应。
添加元组生成器,使其与列表和二进制生成器相对应。
修复推导式限定符中的语法错误,通过显式识别 pattern = value
绑定,并以有意义的方式处理它们。
目前,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,有四种可能的结果
此提案更改了推导式描述的一部分,每个限定符要么是生成器、绑定器或过滤器。
生成器是列表生成器、元组生成器或位字符串生成器。
列表生成器写为
Pattern <- List_Expr
或写为
Pattern [<-] List_Expr
其中 List_Expr 是一个表达式,其必须求值为项的列表。
元组生成器写为
Pattern {<-} Tuple_Expr
其中 Tuple_Expr 是一个表达式,其必须求值为项的元组。
位字符串生成器写为
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 系统的其余部分无需任何更改。
本文档已放入公共领域。