Details
-
Type:
Defect
-
Status:
Closed
-
Resolution: Declined
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
-
Approval:Screened
Description
I came across some strange behavior the other day in clojure.test/are, where the template replacement seems a bit over-eager. As a simple case:
(use 'clojure.test)
(are [x y] (= x y)
'(4 9 16) (map (fn [x] (* x x)) '(2 3 4)))
gives "java.lang.Exception: Unsupported binding form: clojure.lang.LazySeq@7bed76a7", but
(are [x y] (= x y)
'(4 9 16) (map (fn [z] (* z z)) '(2 3 4)))
is fine. It seems that all instances of the variable x get replaced, even the ones in other expressions that are doing the replacing. A macroexpand-1 traced it to clojure.template, and if I patch apply-template there to use postwalk-replace rather than prewalk-replace, clojure.test/are works as I had expected. However, the simple test case I wrote to expose this problem (wrapping deftest around the first example above) fails with what seems to me to be a bizarre error:
[java] FAIL in (can-test-using-local-bindings) (test_clojure.clj:87)
[java] but got :pass
[java] expected: (= (quote (4 9 16)) (map (fn [x] (* x x)) (quote (2 3 4))))
[java] actual: (#<core$EQ clojure.core$EQ@a947850> (4 9 16) (4 9 16))
Can anyone decipher why this fails, or come up with a better solution?
Converted from http://www.assembla.com/spaces/clojure/tickets/372
Attachments:
template-local-binding.patch - https://www.assembla.com/spaces/clojure/documents/bEvfq-BS8r36foeJe5cbLA/download/bEvfq-BS8r36foeJe5cbLA