ipa*_*ian 0 macros eval clojure
我写了一个宏:
(defmacro te
[a b & c]
`(print
~(a b c)))
Run Code Online (Sandbox Code Playgroud)
并运行
(te print 2 inc 4)
Run Code Online (Sandbox Code Playgroud)
得到了一个错误 ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/eval8010 (form-init8519408738377285198.clj:1)
然后我跑
(macroexpand-1 '(te print 2 3 4)
;=> (clojure.core/print (3 4))
Run Code Online (Sandbox Code Playgroud)
这意味着(print 2 (3 4))回归(3 4)?功能print有bug吗?
我的clojure版本1.7.0,JVM版本1.8.0_65-b17
更新
好的,举例不容易理解这个例子.
即使我跑了
(te print 2 inc 4)
user=> (te print 2 inc 4)
;=> 5nil
user=> (macroexpand-1 '(te print 2 inc 4))
;=> (clojure.core/print (inc 4))
Run Code Online (Sandbox Code Playgroud)
它会打印5并返回nil,这意味着(print 2 (inc 4))返回形式(inc 4)?
这完全没有关系print.
这意味着
(print 2 (3 4))回归(3 4)?
这不是它的意思,这就是问题的根源.它的意思是" print用第一个参数调用函数,用2第二个参数调用值(3 4)".表达式(3 4)没有有效值,因为它意味着" 3带参数的调用函数4",这就是你得到异常的原因:3是一个Long(数字)并且不能作为函数调用(在clojure内部,它没有实现IFn函数接口).
作为旁注,如果我理解你想要实现的目标(我可能是错的)你的宏可以很容易地写成一个函数,这通常意味着你应该把它写成一个函数,因为函数更容易处理并与其他功能更好地合作.