Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: How can I bind a variable?

Tags:

clojure

I have the following defined in clojure:

(def ax '(fn x [] (+ 1 z)))

(let [z 4]
    (str (eval ax))
)

:but instead of returning :

5

: I get :

Unable to resolve symbol: z in this context 

: I have tried changing "let" to "binding" but this still does not work. Does anyone know what is wrong here?

like image 476
yazz.com Avatar asked Nov 30 '22 08:11

yazz.com


1 Answers

Making the smallest possible changes to your code to get it to work:

(def ^:dynamic z nil)

(def ax '(fn x [] (+ 1 z)))

(binding [z 4]
    (str ((eval ax)))
)

The two changes are defining z as a dynamic var, so that the name resolves, and putting another paren around (eval ax), because ax is returning a function.

A little bit nicer is to change the definition of ax:

(def ^:dynamic z nil)

(def ax '(+ 1 z))

(binding [z 4]
    (str (eval ax))
)

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

Nicer again is to skip the eval:

(def ^:dynamic z nil)

(defn ax [] (+ 1 z))

(binding [z 5]
    (str (ax))
)

But best of all is to not have z floating around as a var, and pass it in to ax as Mimsbrunnr and Joost suggested.

like image 121
Iain Avatar answered Dec 05 '22 10:12

Iain