【问题标题】:IllegalStateException in nested quote and unquote嵌套引用和取消引用中的 IllegalStateException
【发布时间】:2015-05-23 20:32:24
【问题描述】:

这里是一个来自 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) 

为什么会出现这个错误?

【问题讨论】:

    标签: clojure macros


    【解决方案1】:

    简短回答:您尝试在syntax-quote 之外使用unquote,这没有任何意义。

    更多细节:

    这个错误是由最终的 println 产生的。观察到

    (println ~``~y) 
    

    扩展到

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

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

    当您像这样执行def 时,最终会得到一个var,其初始绑定是cloure.lang.Unbound 类的实例(它是clojure.lang.Var 上的constructors 之一。这个子类clojure.lang.AFn 但是没有指定任何参数;所以它作为函数的每次调用都会调用throwarity,给你这个例外。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      • 2016-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多