正如另一篇文章所述,我正在Clojure中编写一个Shen编译器。
为此,我需要一个接收符号作为参数的宏/函数,如果Shen函数绑定到它,它返回函数,如果符号定义为Clojure宏,它应该返回宏,所以((function or) true false)
应该给出与(or true false)
相同的结果。
我的宏目前看起来像:
(defmacro kl/function [x]
(cl/let [fn (symbol (cl/str (name x) "__fnPoF__"))]
(if (function? fn) `(eval ~fn) `(quote ~x))))
" __ fnPoF __"后缀是因为沉的双重命名空间。 (值和函数可以分配给相同的符号。)
我现在的问题是((function or) true false)
评估为false,因为它的评估结果为('or true false)
,但如果我遗漏了"引用" (x
代替`(quote ~x)
我收到以下例外:
kl=> (function *)
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'kl/*, compiling:(NO_SOURCE_PATH:8)
有人知道如何解决这个问题吗?
答案 0 :(得分:3)
您不能“返回”宏,因为宏没有值。但你可以使(功能或)扩展到符号或;然后通常的Clojure宏扩展/评估机制将做你想要的。所以,虽然我不知道Shen是如何工作的,但似乎只是一个简单的改变:
(defmacro kl/function [x]
(cl/let [fn (symbol (cl/str (name x) "__fnPoF__"))]
(if (function? fn)
`(eval ~fn)
x)))
顺便说一句,eval
等待发生的灾难让我感到震惊。我强烈怀疑eval
对你的目标是必要的。