What is the practical purpose of dynamic vars and clojure bindings?

I looked at the links: http://clojure.org/vars#Vars%20and%20the%20Global%20Environment , http://clojuredocs.org/clojure_core/clojure.core/binding

as well as clojure and ^: dynamic and clojure Dynamic binding

I still do not understand why there is a need for binding in general, since every program I wrote was without them, and I can find ways to write examples in the usual way - which I think is more understandable. Are there examples of projects / software paradigms that use this?

for example ... on an example with animals, you can get a similar effect:

 (def dog {:name "Dog" :sound "Woof"}) (def cat {:name "Cat" :sound "Meow"}) (defn speak [animal] (str (:name animal) " says " (:sound animal)) (println (speak dog)) (println (speak cat)) 

no macros, no dynamic linking ... still very clean.

+8
clojure dynamic-scope
source share
2 answers

There is no strict requirement for them: since you are observing correctly, you can do whatever you like without binding , and indeed, if binding does not exist, you can easily implement it relatively easily using macros and Java ThreadLocal s.

Binding, however, is useful as a way to pass a dynamic context into a function without having to explicitly pass a parameter.

This is especially useful when you compose deeply nested functions of a higher order and do not want to add additional parameters to each individual function in the call stack to pass some value to lower-level functions embedded deep inside.

To build on your example:

 (def ^:dynamic *loud-noises* false) (defn speak [animal] (str (:name animal) " says " (let [sound (:sound animal)] (if *loud-noises* (.toUpperCase sound) sound)))) (speak dog) => "Dog says Woof" (binding [*loud-noises* true] (speak dog)) => "Dog says WOOF" 

Note. I did not need to add an extra parameter to the speak function to get a different behavior. Adding an additional parameter would be trivial in this case, but imagine if the speak function was deeply immersed in a complex function of a higher order .....

However, I think the best advice overall is to avoid dynamic snapping if you really don't need it. It is usually best to add explicit parameters if you can: direct parameters simplify testing and talk about functions.

+11
source share

Just following the mikera example above. I understand why you would do it in a less expressive language, but since clojure is so expressive, I would prefer to rewrite it ... The loud-noise function can be changed slightly, again to achieve the same effect, adding additional parameters to speak. ..

 (defn speak [animal & opts] (let [sound (:sound animal) sound (if (some #(= % :louder) opts) (.toUpperCase sound) sound)] (str (:name animal) " says " sound))) > (speak dog) ;;=> "Dog says Woof" > (speak dog :louder) ;;=> "Dog says WOOF" 

Is binding only a way to crack a quick and dirty solution if you cannot change the source code?

+1
source share

All Articles