递归宏中的负数异常
Negative arity exception in recursive macro
我正在尝试 coding challenge,它要求您创建可以无限编译的代码。
我的第一个想法是永远扩展到自身的宏。我写了:
(defmacro a []
(a))
(a)
这实际上并没有产生任何结果,但我希望它永远循环下去。然而,相反,我得到了一个荒谬的异常:
Wrong number of args (-2) passed to: infinite-compile/a, compiling:...
如果我试图给它一个踢球的参数,它现在会抱怨宏不需要任何参数。
如果我有它实际产生对自身的调用:
(defmacro a []
`(a))
(a)
它因 Whosebug 而失败,这是我所期望的。
这是怎么回事?为什么它认为我正在传递宏“-2”参数?我能想到的唯一可能的事情是它与传递给宏的 2 个隐式 &
参数有关,但这只是在黑暗中拍摄,并不能真正解释发生了什么。
为了解决这个问题,这似乎不是多元数宏的问题,因为它只有 0 元数版本。此外,显式传递隐式参数不会做任何事情:
(defmacro a []
(a &form &env))
这产生:
Compiler Exception clojure.lang.ArityException: Wrong number of args (2) passed to: infinite-compile/a, compiling:
您期望 (a)
在 a
的定义期间进行宏扩展,此时 a
还不知道是一个宏(因此应该是一个函数),而当您引用表单时,您实际上是在构建一个扩展为对自身的调用的宏。
当编译器宏展开宏时,它会在调用与宏关联的函数之前添加隐式参数:Compiler.java#L6795. Here, you are directly calling a
, which is in the scope of the implicit defn
(core.clj#L452),而不传递必要的参数。
我希望以下内容能按您的意愿工作(循环):
user=> (defmacro a[]&form)
#'user/a
user=> (a)
但不幸的是,这是我收到的错误消息:
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'user/a, compiling:(/tmp/form-init5239882861501900074.clj:1:1)
...尽管:
user=> (defmacro a[](print &form))
#'user/a
user=> (a)
(a)nil
注意。 Common Lisp 等价物是:
(defmacro w(&whole w)w) ;; 23 bytes
现有名称
另请注意,一旦您定义了 a
,您就不能按如下方式更改定义:
(defmacro a[](a 0 1))
... 因为它抱怨 a
接受零参数。但是,如果您使用尚未定义的名称定义 另一个 宏,它会起作用:
user=> (defmacro b[](b 0 1))
#'user/b
user=> (b)
WhosebugError user/b (form-init5239882861501900074.clj:1)
有关问题的更多描述,请参阅 http://dev.clojure.org/jira/browse/CLJ-1279 处的票证。
我正在尝试 coding challenge,它要求您创建可以无限编译的代码。
我的第一个想法是永远扩展到自身的宏。我写了:
(defmacro a []
(a))
(a)
这实际上并没有产生任何结果,但我希望它永远循环下去。然而,相反,我得到了一个荒谬的异常:
Wrong number of args (-2) passed to: infinite-compile/a, compiling:...
如果我试图给它一个踢球的参数,它现在会抱怨宏不需要任何参数。
如果我有它实际产生对自身的调用:
(defmacro a []
`(a))
(a)
它因 Whosebug 而失败,这是我所期望的。
这是怎么回事?为什么它认为我正在传递宏“-2”参数?我能想到的唯一可能的事情是它与传递给宏的 2 个隐式 &
参数有关,但这只是在黑暗中拍摄,并不能真正解释发生了什么。
为了解决这个问题,这似乎不是多元数宏的问题,因为它只有 0 元数版本。此外,显式传递隐式参数不会做任何事情:
(defmacro a []
(a &form &env))
这产生:
Compiler Exception clojure.lang.ArityException: Wrong number of args (2) passed to: infinite-compile/a, compiling:
您期望 (a)
在 a
的定义期间进行宏扩展,此时 a
还不知道是一个宏(因此应该是一个函数),而当您引用表单时,您实际上是在构建一个扩展为对自身的调用的宏。
当编译器宏展开宏时,它会在调用与宏关联的函数之前添加隐式参数:Compiler.java#L6795. Here, you are directly calling a
, which is in the scope of the implicit defn
(core.clj#L452),而不传递必要的参数。
我希望以下内容能按您的意愿工作(循环):
user=> (defmacro a[]&form)
#'user/a
user=> (a)
但不幸的是,这是我收到的错误消息:
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'user/a, compiling:(/tmp/form-init5239882861501900074.clj:1:1)
...尽管:
user=> (defmacro a[](print &form))
#'user/a
user=> (a)
(a)nil
注意。 Common Lisp 等价物是:
(defmacro w(&whole w)w) ;; 23 bytes
现有名称
另请注意,一旦您定义了 a
,您就不能按如下方式更改定义:
(defmacro a[](a 0 1))
... 因为它抱怨 a
接受零参数。但是,如果您使用尚未定义的名称定义 另一个 宏,它会起作用:
user=> (defmacro b[](b 0 1))
#'user/b
user=> (b)
WhosebugError user/b (form-init5239882861501900074.clj:1)
有关问题的更多描述,请参阅 http://dev.clojure.org/jira/browse/CLJ-1279 处的票证。