我正在尝试编写一个调用某些函数的宏。这些函数只能由宏使用,因此我将它们放在包装宏的 letfn
中。伪代码:
(letfn [(fn-a [] ...)
(fn-b [] ...)
(fn-c [] (fn-b))]
(defmacro my-macro [stuff]
`(let [whatever# (fn-a)]
(fn-c))))
对 fn-a
和 fn-c
的调用有效,但是当 fn-c
尝试调用 fn-b 时
我得到IllegalStateException: Attempting to call unbound fn: #'name.space/fn-b。这是为什么?
如果我将 fn-b
和 fn-c
放在它们自己的 defn
中,一切正常。但我不想这样做,因为它不干净。
编辑:为了测试,我尝试将函数绑定(bind)放入内部 let
中,但遇到了相同的异常。
最佳答案
我认为这种方式根本行不通。
例如,对 fn-c
的调用扩展为 your.namespace/fn-c
,因此您的代码似乎调用了恰好具有相同名称的其他函数。
但是您没有your.namespace/fn-b
,这会引发异常。
要引用非限定符号,您需要对其进行引号和取消引号:~'fn-a
但这也不起作用,因为局部函数在扩展时没有定义,您只能将它们用于宏本身。
您要么必须在命名空间中定义函数并在宏中限定它们,要么将它们包含在宏扩展中,这将在每次使用时再次定义它们。
关于macros - 非法状态异常 : Attempting to call unbound fn in macro,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25257883/