68 votes

Lier contre la liaison dans Clojure

Je comprends qu’elles sont différentes car on travaille pour régler *compile-path* et on ne le fait pas. Cependant, j'ai besoin d'aide pour savoir pourquoi elles sont différentes.

let crée une nouvelle portée avec les liaisons données, mais binding ...?

106voto

Brian Carper Points 40078

let crée un correspondant a une portée lexicale immuable alias pour une certaine valeur. binding crée de la dynamique d'une portée contraignante pour certains Var.

Liaison dynamique signifie que le code à l'intérieur de votre binding forme et n'importe quel code qui code pour les appels (même si ce n'est dans les locaux de portée lexicale) voir la nouvelle liaison.

Donnée:

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

binding crée en fait une liaison dynamique pour un Var mais let seulement des ombres de la var avec un alias local:

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

binding pouvez utiliser les noms complets (parce qu'il opère sur l' Vars) et let ne peut pas:

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-introduit les liaisons ne sont pas mutables. binding-introduit les liaisons sont thread-localement mutable:

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

Lexicale vs de liaison dynamique:

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

Voir aussi Vars, laissez.

12voto

Marc Points 513

Une autre différence syntaxique pour let vs binding:

Pour la liaison, toutes les valeurs initiales sont évaluées avant qu'aucune d'entre elles ne soit liée aux vars. Ceci est différent de let, où vous pouvez utiliser la valeur d'un "alias" précédent dans une définition ultérieure.

 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
 

9voto

Yuval Adam Points 59423

binding lie une valeur à un nom dans l'environnement global par thread

Comme vous l'avez mentionné, let crée une nouvelle portée pour lesdites liaisons.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X