Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do `vector` and `[...]` sometimes behave differently in Clojure?

In Clojure, the square brackets are a shorthand for defining vectors:

user=> (vector 'a 'b 'c)
[a b c]
user=> ['a 'b 'c]
[a b c]

The documentation page for vector speaks of the long way and the short way of defining vectors.

However, in defn and doseq there seems to be a difference.

user=> (doseq [x (range 1 4)] (printf "%d\n" x)) 
1
2
3
nil
user=> (doseq (vector 'x (range 1 4)) (printf "%d\n" x)) 
IllegalArgumentException doseq requires a vector for its binding in user:1 clojure.core/doseq (core.clj:2935)

What accounts for this difference? Are the square brackets given special status in the reader, or do they sugar some particular form?

like image 638
Ray Toal Avatar asked Sep 14 '15 03:09

Ray Toal


1 Answers

vector is evaluated after macroexpansion, while [] is evaluated at read time, before macros are expanded. In your second case, the doseq macro does not see a vector, it sees a list starting with the symbol vector, since macros are expanded before regular functions are evaluated.

like image 99
noisesmith Avatar answered Oct 18 '22 10:10

noisesmith