let
crea un alias immutabile con lo scope lessicale per un certo valore. binding
crea un binding con ambito dinamico per alcuni Var
.
Il collegamento dinamico significa che il codice all'interno del modulo binding
e qualsiasi codice che tale codice chiama (anche se non nell'ambito lessicale locale) vedrà la nuova associazione.
Dato:
user> (def ^:dynamic x 0)
#'user/x
binding
crea in realtà una dinamica vincolante per un Var
ma let
ombre solo la var con un alias locale:
user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0
binding
possono usare nomi qualificati (dal momento che opera su Var
s) e let
non possono:
user> (binding [user/x 1] (var-get #'x))
1
user> (let [user/x 1] (var-get #'x))
; Evaluation aborted.
;; Can't let qualified name: user/x
let
- i collegamenti introdotti non sono modificabili. binding
attacchi -introduced sono thread-localmente mutevole:
user> (binding [x 1] (set! x 2) x)
2
user> (let [x 1] (set! x 2) x)
; Evaluation aborted.
;; Invalid assignment target
lessicale vs dinamica vincolante:
user> (defn foo [] (println x))
#'user/foo
user> (binding [x 1] (foo))
1
nil
user> (let [x 1] (foo))
0
nil
Vedi anche Vars, let.
fonte
2009-10-06 03:00:49
Questo plus http://en.wikipedia.org/wiki/Scope_(programming)#Static_versus_dynamic_scoping mi ha davvero aiutato. Grazie Signore! – Carl
La x deve essere associata con il suggerimento ^: dinamico per non generare un errore, io credo. – WeGi