macros - 非法状态异常 : Attempting to call unbound fn in macro

标签 macros clojure

我正在尝试编写一个调用某些函数的宏。这些函数只能由宏使用,因此我将它们放在包装宏的 letfn 中。伪代码:

(letfn [(fn-a [] ...)
        (fn-b [] ...)
        (fn-c [] (fn-b))]
  (defmacro my-macro [stuff]
   `(let [whatever# (fn-a)]
      (fn-c))))

fn-afn-c 的调用有效,但是当 fn-c 尝试调用 fn-b 时 我得到IllegalStateException: Attempting to call unbound fn: #'name.space/fn-b。这是为什么?

如果我将 fn-bfn-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/

相关文章:

namespaces - 在 clojure 中,如何取消命名空间中的 var 定义?

eclipse - 如何在 Eclipse 3.5 中录制和重放宏?

c++ - 如何对无符号长数使用宏?

scala - 记录 Scala 2.10 宏

dictionary - Clojure 映射中给定键 "updating"的惯用方式?

clojure - Clojure 属性映射中的歧义

clojure 将协议(protocol)定义保存在与实现不同的命名空间中

c++ - 如何编写可在 C++ 程序中使用的 C 头文件?

c++ - C++ 宏中的随机数

clojure - 使用 Clojure 进行新开发的最佳用例是什么?