我已经阅读了来自的宏教程 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=>
失败并出现同样的错误。
上述代码有什么问题? 提前感谢您提供任何提示/网址/笔记!
DG
答案 0 :(得分: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__)
当*
尝试对n
,factorial_v9
和(dec n)
进行操作时,会导致异常。由于*
对数字进行操作,因此它尝试将factorial_v9
转换为数字并失败。