Clojure 在宏中使用循环
考虑这个最小的例子Clojure 在宏中使用循环,clojure,Clojure,考虑这个最小的例子 (defmacro foo [] `(list ,@(for [i [1 2 3]] (+ 1 i)))) 我希望(foo)扩展到(列表2 3 4) 但是,当我尝试(macroexpand-1(foo) 语法错误宏扩展clojure.core/let at(*cider repl:localhost:43203(clj)*:366:22)。 测试/i-失败:简单符号?位于:[:绑定:形式:本地符号]规范::clojure.core.specs.alpha/local-n
(defmacro foo []
`(list ,@(for [i [1 2 3]] (+ 1 i))))
我希望(foo)
扩展到(列表2 3 4)
但是,当我尝试(macroexpand-1(foo)
语法错误宏扩展clojure.core/let at(*cider repl:localhost:43203(clj)*:366:22)。
测试/i-失败:简单符号?位于:[:绑定:形式:本地符号]规范::clojure.core.specs.alpha/local-name
测试/i-失败:向量?位于:[:绑定:表单:seq destructure]spec::clojure.core.specs.alpha/seq-binding-form
测试/i-失败:映射?位于:[:绑定:形式:映射破坏结构]规范::clojure.core.specs.alpha/map-bindings
测试/i-失败:映射?位于:[:绑定:形式:映射破坏结构]规范::clojure.core.specs.alpha/map-special-binding
出了什么问题?我不能在宏定义中使用
循环吗?,@
应该是~
user=> (defmacro foo []
`(list ~@(for [i [1 2 3]] (+ 1 i))))
#'user/foo
user=> (macroexpand-1 '(foo))
(clojure.core/list 2 3 4)
user=> (foo)
(2 3 4)
#
是不相关的。这里不需要限定变量,因为它们没有引入调用方的作用域。事实上,您刚刚命名了一个变量i#
,这是合法的,但容易混淆。唯一重要的更改是从,
切换到~
。
user=> (defmacro foo []
`(list ~@(for [i [1 2 3]] (+ 1 i))))
#'user/foo
user=> (macroexpand-1 '(foo))
(clojure.core/list 2 3 4)
user=> (foo)
(2 3 4)