如何将列表更改为 Clojure 宏中的代码?
我有以下宏:
(defmacro ss [x]
`(clojureql.core/select
(clojureql.core/table db "users_table")
(clojureql.core/where ~x)
)
)
(macroexpand '(ss '(= :type "special")))
: 但它产生 :
(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where '(= :type "special")))
: 而不是 :
(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where (= :type "special")))
: 我意识到问题是我传递了一个列表 '(= :type "special"),但如何才能在宏中取消引用它?
更新:
感谢 Mikera 的回答,我终于得到了这个工作:
(defn ss [x]
(clojureql.core/select
(clojureql.core/table db "users_table")
x
)
)
(macroexpand '(ss (eval `(clojureql.core/where ~'(= :type "special")))))
虽然输出略有不同,但它按预期工作:
(ss (eval (clojure.core/seq (clojure.core/concat (clojure.core/list 'clojureql.core/where) (clojure.core/list '(= :type "special"))))))
I have the following macro:
(defmacro ss [x]
`(clojureql.core/select
(clojureql.core/table db "users_table")
(clojureql.core/where ~x)
)
)
(macroexpand '(ss '(= :type "special")))
: but it produces :
(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where '(= :type "special")))
: instead of :
(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where (= :type "special")))
: I realise that the problem is I am passing in a list '(= :type "special"), but how can I get this to unquote in the macro?
Update:
I finally got this working thanks to Mikera's answer by doing this:
(defn ss [x]
(clojureql.core/select
(clojureql.core/table db "users_table")
x
)
)
(macroexpand '(ss (eval `(clojureql.core/where ~'(= :type "special")))))
: although the output is slightly different it works as expected:
(ss (eval (clojure.core/seq (clojure.core/concat (clojure.core/list 'clojureql.core/where) (clojure.core/list '(= :type "special"))))))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在我看来,您将错误的东西传递给了 Macroexpand:您可能应该使用:
即您只需要在开头引用一个引号来引用整个表达式。
Looks to me like you're passing the wrong thing to macroexpand: you should probably use:
i.e. you ony need one quote at the beginning to quote the entire expression.
您不能将运行时参数传递给宏,因为前者仅在运行时才知道,而后者已经在编译时扩展和编译。
您必须使用一个函数。
You cannot pass runtime arguments to macros since the former are only known at - well - runtime, while the latter are already expanded and compiled at - well - compile time.
You must use a function.