为什么 `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
谈到了定义向量的长路和短路。
但是,在defn
和doseq
中似乎有所不同。
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
开头的列表,因为在评估常规函数之前扩展了宏。
在Clojure中,方括号是一个shorthand用于定义向量:
user=> (vector 'a 'b 'c)
[a b c]
user=> ['a 'b 'c]
[a b c]
The documentation page for vector
谈到了定义向量的长路和短路。
但是,在defn
和doseq
中似乎有所不同。
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
开头的列表,因为在评估常规函数之前扩展了宏。