【问题标题】:Purpose of "let expression" (LetExpr) in the Java compiler?Java 编译器中“let 表达式”(LetExpr) 的用途?
【发布时间】:2012-01-12 10:21:59
【问题描述】:

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

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

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

这当然不被语言的语法所接受,并在早期的编译器阶段被拒绝。

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

javac内部使用的还是其他工具合成的?它是否可能只是 Java 早期的产物,来自从未见识过的语言特性?

今天有什么有用的东西可以用它来做吗?

一般来说,它为什么存在?

【问题讨论】:

    标签: java compiler-construction language-design let


    【解决方案1】:

    一般来说,它为什么存在?

    正如谷歌所建议的那样,它存在用于自动装箱。

    如果你有这样的代码:

    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 级别的转换以简化编译。

    【讨论】:

    • 该页面没有说它存在用于自动装箱,只是说它用于自动装箱。由于该页面是关于自动装箱中的一个错误,而不是关于 let 表达式,因此自动装箱是它提到的 let 表达式的唯一用途也就不足为奇了。 (我并不是说你错了——我真的不知道——但我认为添加一个更相关/令人信服/明确的来源会有所帮助,如果你知道的话。)
    • let int foo_helper = foo.intValue() in foo_helper++; 是什么意思?
    • @ArtB 类似于 ml 语法。让 var = 表达式中的值。因此,在表达式中,var 的所有实例都计算为 value。
    • let int foo_helper = foo.intValue() in foo_helper++; { int foo_helper = foo.intValue(); foo_helper++; } 有何不同?它似乎是一个指针,不是吗?在第二个表达式中, foo 的值不会在表达式之后更新
    【解决方案2】:

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

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

    我能想到很多语言在用户编写的源代码中使用它(Haskell、ML、Scheme、SBCL、Arc,...),所以不确定你是怎么没看到的。 ..

    或者你的意思只是在 Java 中?

    let x = 2 in (x + 5)
    

    是以下的简写:

    (\x (x + 5)) 2
    

    最终会简化为

    (2 + 5)
    

    \ 应该是 lambda。

    至于为什么它在 Java 中,不确定。它应该做的是声明变量,所以检查它是否在那里使用。

    【讨论】:

    • 在严格的函数式语言(例如 ML、Scheme)中,使用 let 绑定与写出表达式完全不同,因为表达式必须在绑定的点进行计算。对于 Java,最有可能想到的用途是将具有副作用的代码转换为静态单一赋值形式,这样更容易分析以生成优化的字节码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    相关资源
    最近更新 更多