Java编译器中“ let表达式”(LetExpr)的目的?


71

Java编译器似乎支持(查找)中的let表达式。com.sun.tools.javac.tree.*LetExpr

JCTree中的一条评论甚至提到了一些语法

(let int x = 3; in x+2)

当然,哪种语言不会被该语言的语法接受,而在较早的编译器阶段会被拒绝。

我想知道这个构造的起源,这是我以前从未见过的。

它是在内部使用javac还是由其他工具综合使用?难道这仅仅是Java早期的一种人工产物,它是一种从未见过光的语言功能?

今天有什么可以用的吗?

一般来说,为什么存在?

Answers:


46

一般来说,为什么存在?

正如Google建议的那样,它可以自动装箱。

如果您有这样的代码:

Integer foo = 0;
foo++;

Java在内部将其添加到此辅助表达式中:

Integer foo = 0;
let int foo_helper = foo.intValue() in foo_helper++;

来源:http//bugs.sun.com/bugdatabase/view_bug.do?bug_id = 6614974

该表达式显然没有语法表示形式,它只是AST级别的转换,以简化编译。


14
该页面并没有说它存在于自动装箱中,只是说它用于自动装箱中。由于该页面是关于自动装箱中的错误,而不是关于let表达式,因此自动装箱是其中提到的let表达式的唯一用法也就不足为奇了。(我并不是说您错了-我真的不知道-但我认为添加一个更相关/令人信服/明确的信息源将很有帮助。)
ruakh

3
let int foo_helper = foo.intValue() in foo_helper++;甚至是什么意思?
雪橇

1
@ArtB它类似于ml语法。令var =表达式中的值。因此,在表达式中,var的所有实例都求值。
马修

2
如何let int foo_helper = foo.intValue() in foo_helper++; 不同{ int foo_helper = foo.intValue(); foo_helper++; }?好像是指针,不是吗?在第二个表达式中,foo的值将不会在表达式之后更新
Kip

4

这称为let形式,用于“缩写”。

另一方面,在过程语言中,这称为“声明变量”,因为变量的“值”单元格可能会在过程语言中发生变异。(在函数式语言中,它只是缩写,与只写它没什么不同)

我可以想到很多语言在用户编写的源代码中使用了它(Haskell,ML,Scheme,SBCL,Arc等),所以不确定您如何看待它...

还是您只是想用Java?

let x = 2 in (x + 5)

是以下方面的简写:

(\x (x + 5)) 2

最终将减少为

(2 + 5)

哪里 \应该lambda。

至于为什么要用Java,则不确定。它应该做的是声明变量,因此请检查是否在其中使用了它。


1
在严格的功能语言(例如ML,Scheme)中,使用let绑定与写出表达式完全不同,因为必须在绑定表达式的位置对表达式进行求值。Java想到的最可能的用法是将具有副作用的代码转换为“静态单一分配”形式,可以更轻松地对其进行分析以生成优化的字节码。
Nate CK
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.