70

The Java compiler seems to have support for let expressions in com.sun.tools.javac.tree.* (look for LetExpr).

One comment in JCTree even mentions some syntax

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

which of course is not accepted by the grammar of the language and rejected in an earlier compiler phase.

I'm wondering about the origin of this construct, which I have never seen before.

Is it used internally by javac or is it synthesized by other tools? Is it maybe just an artifact from the very early days of Java from a language feature which never saw the light?

Is there anything useful which can be done with it today?

Generally speaking, why does it exist?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
soc
  • 27,983
  • 20
  • 111
  • 215

2 Answers2

46

Generally speaking, why does it exist?

It exists for autoboxing as Google suggests.

If you have code like this:

Integer foo = 0;
foo++;

Java internally makes this into this helper expression:

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

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

That expression obviously has no syntax representation, it's just an AST level transformation to simplify compilation.

Armin Ronacher
  • 31,998
  • 13
  • 65
  • 69
  • 14
    That page doesn't say that it *exists* for autoboxing, only that it's *used* in autoboxing. Since the page is about a bug in autoboxing, not about let-expressions, it's not surprising that autoboxing is the only use for let-expressions that it mentions. (I'm not saying you're wrong -- I really don't know -- but I think it would be helpful to add a more relevant/convincing/explicit source, if you know of one.) – ruakh Dec 04 '11 at 01:46
  • 3
    what does `let int foo_helper = foo.intValue() in foo_helper++;` even mean? – Sled Dec 04 '11 at 07:26
  • 1
    @ArtB Its similar to ml syntax. let var = value in expression. Thus in the the expression, all instances of var evaluate to value. – Matthew Dec 04 '11 at 19:17
  • 2
    How is `let int foo_helper = foo.intValue() in foo_helper++; ` different from `{ int foo_helper = foo.intValue(); foo_helper++; }`? It seems to be something like a pointer, no? In the second expression, the value of foo would not be updated after the expression – Kip Dec 08 '11 at 18:33
4

This is called the let form and is used for "abbreviating".

On the other hand, in procedural languages this is called "declaring a variable" because the variable's "value" cell can mutate in procedure languages. (In functional languages, it's just an abbreviation and no different to just writing it out in the first place)

I can think of a lot of languages that use it in the source code the language user writes (Haskell, ML, Scheme, SBCL, Arc, ...), so not sure how you didn't see it yet...

Or did you mean just in Java?

let x = 2 in (x + 5)

Is shorthand for:

(\x (x + 5)) 2

which will eventually be reduced to

(2 + 5)

where \ is supposed to be lambda.

As for why it's in Java, not sure. What it's supposed to do is declare variables, so check whether it's used there.

Yi Jiang
  • 49,435
  • 16
  • 136
  • 136
  • 1
    In a strict functional language (e.g. ML, Scheme), using a let binding is quite different from writing out the expression because the expression must be evaluated at the point where it is bound. The most likely use of this that comes to mind for Java is to convert code with side-effects to Static Single Assignment form, which is more easily analyzed to produce optimized bytecode. – Nate C-K Dec 06 '11 at 18:15