Clojure: How to bind a variable?

Clojure has the following:

(def ax '(fn x [] (+ 1 z))) (let [z 4] (str (eval ax)) ) 

: instead of returning:

 5 

: I get:

 Unable to resolve symbol: z in this context 

: I tried changing the "let" to "binding", but this still does not work. Does anyone know what's wrong here?

+4
source share
3 answers

Making minimal changes to the code to make it work:

 (def ^:dynamic z nil) (def ax '(fn x [] (+ 1 z))) (binding [z 4] (str ((eval ax))) ) 

Two changes define z as a dynamic var, so the name resolves and puts another pair around (eval ax), because ax returns a function.

A little nicer to change the definition of ax:

 (def ^:dynamic z nil) (def ax '(+ 1 z)) (binding [z 4] (str (eval ax)) ) 

So, ax evaluation immediately gets the result you want, rather than returning a function that does this.

Try skipping eval again:

 (def ^:dynamic z nil) (defn ax [] (+ 1 z)) (binding [z 5] (str (ax)) ) 

But it’s best not to have z floating around like var and pass it to the ax, as suggested by Mimsbrunnr and Joost.

+11
source

The short answer is not to use eval. You almost never need, and certainly not here.

For instance:

 user> (defn ax [z] (+ 1 z)) #'user/ax user> (let [f #(ax 4)] (f)) 5 
+8
source

So I'm not quite sure what you are doing here.

I mean this works, although it does not use eval, defining x as a function (fn [ x ] (+ x 1))

 > (def x #(+ 1 %)) #'sandbox102711/x > (x 4) 5 

After all, eval is not something you should use. As support> cljoure for lambda abstraction and macros (see fn definition above) should eliminate the need.

+1
source

Source: https://habr.com/ru/post/1345326/


All Articles