Difference between binding and binding
What is the difference between Clojure functions binding
and with-bindings
? They seem to do the same thing, but with slightly different syntax.
with bindings is useful when you need to dynamically choose what to bind . here's a fun example where we arbitrarily choose what to bind:
user> (def ^:dynamic a)
#'user/a
user> (def ^:dynamic b)
#'user/b
user> (binding [a 1
b 2]
(+ a b))
3
user> (with-bindings (if (rand-nth [true false])
{#'a 1
#'b (rand-int 10)}
{#'a 1
#'b 2})
(+ a b))
3
user> (with-bindings (if (rand-nth [true false])
{#'a 1
#'b (rand-int 10)}
{#'a 1
#'b 2})
(+ a b))
3
user> (with-bindings (if (rand-nth [true false])
{#'a 1
#'b (rand-int 10)}
{#'a 1
#'b 2})
(+ a b))
1
if you try it with with bind
it will get frustrated that it didn't pass a literal vector as an anchor shape.
user> (binding (if (rand-nth [true false])
{#'a 1
#'b (rand-int 10)}
{#'a 1
#'b 2})
(+ a b))
IllegalArgumentException binding requires a vector for its binding in user:138 clojure.core/binding (core.clj:1865)
It actually does the same thing:
(def ^:dynamic x 1)
;;=> #'user/x
x
;;=> 1
(with-bindings {#'x 2}
x)
;;=> 2
You may notice a slight difference in the input parameters: binding
accepts characters, while with-bindings
accepts variables. Also, as mentioned above, since it with-bindings
takes a map, you can compose it dynamically based on your application logic.