查看一个非官方的 OCaml 语法,这个网站上唯一出现 begin
的产生式为:
Expression ::= begin Expression end
再往下一点,就会看到:
Expression ::= ( Expression [:Type] )
结合一些微不足道的代码中begin
/end
被替换为(
/)
(没有影响正确性),这可能表明begin
end
关键字只是语法糖。 或者我漏掉了什么?
begin .. end
不是“语法糖”,它与 (..)
是冗余的,因为它们做完全相同的事情。 begin .. end
包含一个用于副作用执行的命令式表达式,以及 (..)
表示具有非单元值的表达式。但编译器并不强制要求这样使用,语言设计者只是认为这样使用看起来更好看而已。expr ::= '(' expr ')'
)。()
还表示类型为 unit
的常量,而 begin end
也允许在此处使用 - 但是这最后一个并未在手册中指定,只有实现方面得到了一致的支持。
但是,括号还可以用于:
function (_::_)::_ -> ...
Array.get
和 Array.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)
。
begin .. end
翻译为( .. )
,那么前者就是语法糖。但是在任何有意义的意义上,编译器并没有这样做。相反,两种结构都隐含地编码在AST的构建中。一个结构不会被翻译为另一个结构。 - Pascal Cuoq