OCaml中的begin..end是语法糖吗?

14

查看一个非官方的 OCaml 语法,这个网站上唯一出现 begin 的产生式为:

Expression ::= begin Expression end

再往下一点,就会看到:

Expression ::= (   Expression  [:Type]   )

结合一些微不足道的代码中begin/end被替换为(/)(没有影响正确性),这可能表明beginend关键字只是语法糖。 或者我漏掉了什么?

2个回答

31
“语法糖”意味着将某种简单但不是平凡的结构转换成其他结构。 begin .. end 不是“语法糖”,它与 (..)冗余的,因为它们做完全相同的事情
如果您感兴趣,设计者的意图是让程序员使用 begin .. end 包含一个用于副作用执行的命令式表达式,以及 (..)表示具有非单元值的表达式。但编译器并不强制要求这样使用,语言设计者只是认为这样使用看起来更好看而已。

4
谁说语法糖必须是不重要的呢?这句话到底什么意思?毫无疑问,我会把begin-end分类为语法糖。 - Andreas Rossberg
5
如果OCaml编译器在内部将begin .. end翻译为( .. ),那么前者就是语法糖。但是在任何有意义的意义上,编译器并没有这样做。相反,两种结构都隐含地编码在AST的构建中。一个结构不会被翻译为另一个结构。 - Pascal Cuoq
4
如果我的回复给您带来了不良的印象,我向您道歉。我只是在质疑您的定义,因为额外的条件似乎相当随意,而且这是我第一次听说有人将非平凡性作为一个标准。同样,“一个不被翻译成另一个”是一个实现细节,所以我不明白它有多重要。(关于分离编译的辩论,我不知道该说什么,除了争辩链接并没有支持您的实际陈述,正如其他人也指出的那样。) - Andreas Rossberg
5
Pascal,非常抱歉,但我必须再次反对你的意见。讨论答案就是评论的作用,对吧?(除了风格外,我承认你可以起到一定影响。)假设你发现一个答案有错误或者完全是错的,你会无言以对吗?这样会有谁受益呢? - Andreas Rossberg
OCaml文档似乎在这里将该结构称为语法糖:https://ocaml.org/docs/if-statements-and-loops - undefined
显示剩余2条评论

10
实际上,在 OCaml 语法中,括号有几种不同的语法规则用途,并非所有这些规则都可以与 begin..end 一起使用。括号和 begin..end 可以作为无语义的表达式定界符来消除歧义(就像您所说的 expr ::= '(' expr ')')。() 还表示类型为 unit 的常量,而 begin end 也允许在此处使用 - 但是这最后一个并未在手册中指定,只有实现方面得到了一致的支持。

但是,括号还可以用于:

  • 分隔模式:function (_::_)::_ -> ...
  • 作为 Array.getArray.set 的语法糖:t.(i) t.(i) <- e
  • 用于表达式和模式中的类型注释:(e : t)(这不是定界符的特殊情况,因为没有括号是无效的)
  • 用于子类型强制转换:(e :> t)(e : s :> t)
  • 形成带标签的模式复合:fun ~(x:int) ..fun ?(x=10) ..
  • 在语法的模块、签名和类/对象部分的各种相关位置(强制转换、注释等)中使用

对于这些用途,不能使用 begin..end 替代括号,因此系统地将 ( 替换为 begin,并将 ) 替换为 end 绝对是无效的(反之亦然是正确的)。

抱歉给出了这么严谨的答案,但问题本身已经非常明确了。我不确定 begin..end 处理是否是 OCaml 语法中最优雅的部分(它有很多缺陷)。人们希望它们真正等价,但是那样做没有什么意义,还不如坚持写 (x : int)


1
Pedantic 意味着精确,带有过度精确的强烈内涵。在我看来,你的回答很精确。 - Str.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接