Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure binding of dynamic var not working as expected

Tags:

clojure

From what I understand, setting a new binding on a dynamic var affects all functions called within that binding, and all functions called from those functions.

Why does the binding appear to be lost in the first example below?

(def ^:dynamic *out-dir* "/home/user")

(binding [*out-dir* "/home/dave"] (map #(str *out-dir* %) [1 2 3]))
; gives:    ("/home/user1" "/home/user2" "/home/user3")
; expected: ("/home/dave1" "/home/dave2" "/home/dave3")

(binding [*out-dir* "/home/dave"] (conj (map #(str *out-dir* %) [1 2 3]) *out-dir*))
; gives: ("/home/dave" "/home/dave1" "/home/dave2" "/home/dave3")
like image 838
David Vail Avatar asked Dec 18 '22 22:12

David Vail


1 Answers

This is caused by lazyness - map returns a lazy sequence which is defined inside the binding but is evaluated outside. You need to force the evaluation from inside:

(binding [*out-dir* "/home/dave"] 
  (doall (map #(str *out-dir* %) [1 2 3])))
like image 109
Lee Avatar answered Feb 12 '23 22:02

Lee