Let vs. Binding in Clojure

Rozumiem, że są różne, ponieważ jeden pracuje dla ustawienia *compile-path*, a drugi nie. jednak potrzebuję pomocy, dlaczego są różne.

let tworzy nowy zakres z podanymi wiązaniami, ale binding...?

Author: Prince John Wesley, 2009-10-06

3 answers

let tworzy niezmienny alias o zasięgu leksykalnym dla pewnej wartości. binding tworzy dynamicznie skalowane Wiązanie dla niektórych Var.

Dynamiczne Wiązanie oznacza, że kod wewnątrz formularza binding i każdy kod, który ten kod wywoła (nawet jeśli nie znajduje się w lokalnym zakresie leksykalnym), zobaczy nowe Wiązanie.

Podane:

user> (def ^:dynamic x 0)
#'user/x

binding w rzeczywistości tworzy dynamiczne powiązanie dla Var, ale let tylko cieniuje var z lokalnym aliasem:

user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0

binding może korzystać z kwalifikowanych nazwy (ponieważ działa na Var s) I let nie mogą:

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-wprowadzone wiązania nie są zmienne. binding - wprowadzone wiązania są mutowalne lokalnie:

user> (binding [x 1] (set! x 2) x)
2
user> (let [x 1] (set! x 2) x)
; Evaluation aborted.
;; Invalid assignment target

Wiązanie leksykalne vs. dynamiczne:

user> (defn foo [] (println x))
#'user/foo
user> (binding [x 1] (foo))
1
nil
user> (let [x 1] (foo))
0
nil

Zobacz też Vars, let .

 103
Author: Brian Carper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 14:31:43

Jeszcze jedna różnica składniowa dla let vs binding:

W przypadku wiązania, wszystkie wartości początkowe są obliczane, zanim któreś z nich zostanie powiązane z var. Różni się to od let, gdzie można użyć wartości poprzedniego "aliasu" w późniejszej definicji.

user=>(let [x 1 y (+ x 1)] (println y))
2
nil

user=>(def y 0)
user=>(binding [x 1 y (+ x 1)] (println y))
1
nil
 12
Author: Marc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-21 02:53:01

binding wiąże wartość z nazwą w globalnym środowisku per-thread

Jak już wspomniałeś, let tworzy nowy zakres dla wspomnianych wiązań.

 9
Author: Yuval Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-06 02:16:03