为什么 `vector` 和 `[...]` 有时在 Clojure 中表现不同?

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

在Clojure中,方括号是一个shorthand用于定义向量:

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

The documentation page for vector 谈到了定义向量的长路和短路。

但是,在defndoseq中似乎有所不同。

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)

造成这种差异的原因是什么?方括号在 reader 中是否具有特殊地位,或者它们是某种特殊形式的糖?

vector 在宏展开之后求值,而 [] 在读取时在宏展开之前求值。在你的第二种情况下,doseq 宏看不到向量,它看到以符号 vector 开头的列表,因为在评估常规函数之前扩展了宏。