Haskell RecordDotSyntax语言扩展建议(已接受)

2020-09-21 09:11:06

作为这项提案的领头羊,我很高兴地说,GHC指导委员会终于得出了一个结论:我们接受这项提案,但需要进行最终修改(参见“接下来会发生什么”),并附带一些关于语法的额外细节(参见“我们的结论”)。

该提案完全是关于语法的;特别是关于引入用于记录字段选择的表单r.x。不建议对基础类型系统或语言的任何其他方面进行更改。最初的提案更详细,但经过简化,重点放在了要点上。

记录构成了一个特别丰富和复杂的设计空间,并引发了异常广泛的意见。这项提案吸引了500多条评论,创下了GHC提案的纪录。

这种不同的意见反映在委员会中,如果你阅读委员会的电子邮件讨论,你就会看到这一点。

对不同意见的一种可能的反应是什么都不做,等待清晰的出现。这通常是正确的选择,但在这种情况下(我强烈相信)。我们已经等了很长时间了--关于这个话题我已经争论了二十多年了--我想是时候做出决定了。不过,细节很重要。所以我们这样做了:

我们整理了一个选项列表,您可以在这里找到,其中包括拒绝(一些成员主张的)。鼓励成员添加他们认为缺少的任何选择,并澄清提供的任何选择,以便每个人都能理解。(关于ELM“裸选择器”可能性的说明,其中裸选择器是普通函数:没有成员要求添加此选项。)。

一旦讨论结束,我就进行投票。我们使用Condorcet算法进行投票,不仅考虑了人们的首选,而且考虑了他们选择的顺序。这个过程允许我们表达自己的喜好,同时尊重别人可能有不同观点的事实。

令人高兴的是,有一个明显的赢家:选择(C2a)以7:4或更多的优势击败了所有其他选择。具体情况如下:

形式.x或.x.y.z是一个新的词位,称为“裸选择符”。

裸选择符是非法的,除非用括号括起来,(.x.y.z)表示(\r->;r.x.y.z);也就是说,它是记录选择符。因此,您可以编写map(.x)rs来将选择器映射到记录列表上。

“r.”没有紧跟在“x”后面的是两个词位“r”和“.”,即函数组合。因此(r.x)表示(r.。x)。

表单r.x(点的两边都没有空格)不会被视为裸记录选择器;相反,它会被视为原子表达式,非常类似于限定名M.x。所以f,r.x意味着f(r.x)。

如果r用带括号的表达式替换,情况也一样。所以f(G3).x的意思是f((G3).x)。或者一般而言,任何原子表达式,例如[a,b]。

F r.x表示f(r.x)f M.n.x表示f(M.n.x)f M.N.x表示f(M.n.x)f r.x是非法的f(Gr).x表示f((Gr).x)f(Gr).x是非法的。

如你所见,这是一个相当保守的选择。我们花了很多时间讨论更具表现力的选项。特别是,我们将裸选择器视为后缀运算符,因此。

F.x.y.z表示f.x.y.z f.x 3.y 4表示((F.X)3).y 4

允许选择器之间的空格。在委员会讨论的选择中,你可以看到这一想法的许多变体。但目前我们选择了一条更保守的道路。通过将裸体记录选择器定为非法(除了在单元格中),我们把这些可能性留给了将来,因为我们获得了更多的经验。(这是不采用ELM使用不带括号的裸记录选择器的原因之一。)。

另一个原则是应该可以将变量替换为它绑定到的表达式,这样无论您可以在哪里编写r.x,您也可以编写(F3).x。

我想邀请作者更新他们的提案,将(C2A)纳入其中,特别是。

写出对语法的更改,特别是如何处理指定aexp2.x(参见注释5)。

要解决字段名是运算符时会发生什么的问题(请参见备注6)。

很多人参与了这次对话--谢谢!事实是,我们并非都100%同意--人们的判断是不同的。许多人,也许大多数人(包括我自己)都会做出不同的选择,让他们自己去做。但我们有办法解决这种判断分歧,我们已经执行了这一方法,我尊重这一结论。