繁体   English   中英

嵌套引用和取消引用中的IllegalStateException

[英]IllegalStateException in nested quote and unquote

这是来自Clojure的喜悦的示例:

(let [x 9, y '(- x)]
  (println `y)
  (println ``y)
  (println ``~y)
  (println ``~~y))

repl的输出:

typedclj.macros/y
(quote typedclj.macros/y)
typedclj.macros/y
(- x)

如果我稍微重新调整引用/取消引用的顺序,结果仍然相同(我想知道为什么):

(let [x 9, y '(- x)]
  (println `y)
  (println ``y)
  (println `~`y)
  (println `~`~y))

但是如果我将波浪号放在前面:

(let [x 9, y '(- x)]
  (println `y)
  (println ``y)
  (println `~`y)
  (println ~``~y))

我收到一个奇怪的错误:

CompilerException java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote, compiling:(/Users/kaiyin/personal_config_bin_files/workspace/typedclj/src/typedclj/macros.clj:1:25) 

为什么会出现此错误?

简短的答案:您正试图在syntax-quote之外unquote syntax-quote ,但这没有任何意义。

更多细节:

此错误是从最终println生成的。 观察一下

(println ~``~y) 

扩展到

(println (unquote (syntax-quote (syntax-quote (unquote y))))

这是由于~和反引号字符是阅读器宏而发生的。 扩展unquote实际上不是正常函数或宏。 这是一种特殊形式,仅在syntax-quote内定义。 您可以在编译器源代码LispReader.java中看到这一点 当您在syntax-quote形式之外使用它时,reader宏仍然发生,但是没有诸如“ unquote”之类的功能。 core.clj(第一个定义)中只有一个裸(def unquote) )。

当你做一个def一样,你最终有一个变种,其最初的结合是类的一个实例cloure.lang.Unbound (它是一个构造函数clojure.lang.Var 。这个子类clojure.lang.AFn但没有按没有指定任何Arities;因此,每次将其作为一个函数调用throwarity调用throwarity ,从而给您带来此异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM