Ray Toal
Ray Toal

Reputation: 88378

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?

Upvotes: 5

Views: 206

Answers (1)

noisesmith
noisesmith

Reputation: 20194

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.

Upvotes: 8

Related Questions