1

我已经阅读了来自 http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-i-getting.html站点的宏教程,但我不明白如何调试一些错误。有人可以描述什么是错误的/不正确的吗?

  • 简单版
(defmacro dbgm_v1 [s] 
   (list 'let ['a s] (list 'println (list 'quote s) "=" 'a) 'a)
)
;;;;
(defn factorial_v1 [n] 
   (if (< n 2) n
        (dbgm_v1 (* n factorial_v1(dec n)) )
    ) 
)
;;

; let's test it
(factorial_v1 5) 
ClassCastException clojure.dg.alfa01$factorial_v1 cannot be cast to java.lang.Number  clojure.lang.Numbers.multiply (Numbers.java:146)
  • 复杂的版本
(defmacro dbgm_v9 [x] 
  `(let  [x# ~x] (println '~x "=" x#) x#)
)
;
(defn factorial_v9 [n]
  (if (< n 2) n
    (dbgm_v9 (* n factorial_v9 (dec n)))
))
;
user=> (factorial_v9 5)
ClassCastException clojure.dg.alfa01$factorial_v9 cannot be cast to java.lang.Nu
mber  clojure.lang.Numbers.multiply (Numbers.java:146)
user=>

它失败并出现相同的错误。

上面的代码有什么问题?提前感谢您的任何提示/网址/注释!

危险品

4

1 回答 1

1

您缺少左括号。

(defmacro dbgm_v9 [x] 
  `(let  [x# ~x] (println '~x "=" x#) x#))

(defn factorial_v9 [n]
  (if (< n 2) n
    (dbgm_v9 (* n (factorial_v9 (dec n))))))
                 ;^ Missing (
(factorial_v9 5) ;=> 120

您可以验证您的宏是如何扩展的macroexpand

(macroexpand '(dbgm_v9 (* n factorial_v9 (dec n))))
;=>
(let* [x__31341__auto__ (* n factorial_v9 (dec n))]
  (clojure.core/println (quote (* n factorial_v9 (dec n))) "=" x__31341__auto__)
  x__31341__auto__)

*尝试对 、 和 进行操作nfactorial_v9导致异常(dec n)。由于*对数字进行操作,因此它尝试转换factorial_v9为数字并失败。

于 2013-09-23T03:15:15.520 回答