2011-12-04 8 views
70

Il compilatore Java sembra supportare le espressioni let in com.sun.tools.javac.tree.* (cercare LetExpr).Scopo di "let expression" (LetExpr) nel compilatore Java?

Un commento in JCTree menziona anche qualche sintassi

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

che naturalmente non è accettato dalla grammatica della lingua e ha respinto in una fase precedente del compilatore.

Mi chiedo sull'origine di questo costrutto, che non ho mai visto prima.

Viene utilizzato internamente da javac o è sintetizzato da altri strumenti? È forse solo un artefatto fin dai primi giorni di Java da una funzionalità linguistica che non ha mai visto la luce?

C'è qualcosa di utile che può essere fatto con esso oggi?

In generale, perché esiste?

risposta

43

In generale, perché esiste?

Esiste per l'autoboxing come suggerisce Google.

Se si dispone di codice come questo:

Integer foo = 0; 
foo++; 

Java rende internamente questo in questa espressione aiutante:

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

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

Quell'espressione ha ovviamente alcuna rappresentanza della sintassi, è solo una trasformazione di livello AST per semplificare la compilazione.

+13

Quella pagina non dice che * esiste * per l'autoboxing, solo che è * usato * in autoboxing. Dato che la pagina tratta di un bug nella autoboxing, e non delle let-expression, non sorprende che l'autoboxing sia l'unico uso per le espressioni esplicite che menziona. (Non sto dicendo che ti stai sbagliando - davvero non lo so - ma penso che sarebbe utile aggiungere una fonte più rilevante/convincente/esplicita, se ne conosci uno.) – ruakh

+3

cosa fa 'lascia int foo_helper = foo.intValue() in foo_helper ++; 'even mean? – ArtB

+1

@ArtB È simile alla sintassi ml. lascia var = value in expression. Pertanto nell'espressione, tutte le istanze di var valutano il valore. – Matthew

3

Questo è chiamato il modulo let e viene utilizzato per "abbreviare".

D'altra parte, nei linguaggi procedurali questo viene chiamato "dichiarazione di una variabile" perché la cella "valore" della variabile può mutare nei linguaggi della procedura. (In lingue funzionali, è solo un'abbreviazione e non è diverso da solo scriverlo in primo luogo)

Posso pensare a molte lingue che lo usano nel codice sorgente che l'utente della lingua scrive (Haskell, ML, Scheme, SBCL, Arc, ...), quindi non sei sicuro di come non l'hai ancora visto ...

O intendevi solo in Java?

let x = 2 in (x + 5) 

è una scorciatoia per:

(\x (x + 5)) 2 

che alla fine si riduce a

(2 + 5) 

dove \ si suppone che sia lambda.

Per quanto riguarda il motivo per cui è in Java, non sono sicuro. Quello che deve fare è dichiarare le variabili, quindi controlla se è usato lì.

+1

In un linguaggio funzionale rigoroso (ad es. ML, Schema), l'utilizzo di un legame let è molto diverso dalla scrittura dell'espressione perché l'espressione deve essere valutata nel punto dove è legato. L'uso più probabile di ciò che viene in mente per Java è convertire il codice con effetti collaterali in modulo Static Single Assignment, che è più facilmente analizzato per produrre bytecode ottimizzato. –