Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 为什么我的宏是';在函数调用之前,是否未计算s窗体?_Macros_Clojure - Fatal编程技术网

Macros 为什么我的宏是';在函数调用之前,是否未计算s窗体?

Macros 为什么我的宏是';在函数调用之前,是否未计算s窗体?,macros,clojure,Macros,Clojure,我有以下Clojure代码: (defn mul [a b] (* a b)) (defmacro create-my-macro [macroname] `(defmacro ~macroname [a# b#] (mul a# b#))) (create-my-macro my-mul) (my-mul 1 2) ;; => 2 (my-mul (+ 1 1) 2) ;; => ClassCastException clojure.lang.Pers

我有以下Clojure代码:

(defn mul [a b]
  (* a b))

(defmacro create-my-macro [macroname]
    `(defmacro ~macroname [a# b#]
      (mul a# b#)))

(create-my-macro my-mul)

(my-mul 1 2)
;; => 2
(my-mul (+ 1 1) 2)
;; => ClassCastException clojure.lang.PersistentList cannot be cast to java.lang.Number
当我用
eval
将参数包装在
mul
调用中时,我得到了我想要的答案:

(mul (eval #a) (eval #b))
(macroexpand '(create-my-macro my-mul))
;; => (do
;;      (clojure.core/defn my-mul 
;;        ([&form &env a__58__auto__ b__59__auto__] 
;;          (foo/mul a__58__auto__ b__59__auto__)))
;;      (. (var my-mul) (setMacro)) (var my-mul))

(macroexpand '(my-mul (+ 1 1) 2))
;; => ClassCastException clojure.lang.PersistentList cannot be cast to java.lang.Number  clojure.lang.Numbers.multiply (Numbers.java:146)
但我不明白为什么有必要这样做:如果直接定义了
mymul
宏(而不是通过另一个宏),它就可以工作了。例如,以下方法可以很好地工作:

(defmacro my-mul [a b] `(mul ~a ~b))
(my-mul (+ 1 1) 2)
;; => 4
为什么我会看到这种行为


编辑:以下是失败案例的宏扩展(即不使用
eval
):


如图所示,您希望发出的代码如下所示:

(defmacro my-mul [a b] `(mul ~a ~b))
因此,您需要对其进行语法引用,并在所有局部变量后面加上#:

因此,发出宏的宏应为:

(defmacro create-my-macro [macroname]
    `(defmacro ~macroname [a# b#]
       `(mul ~a# ~b#)))

如图所示,您希望发出的代码如下所示:

(defmacro my-mul [a b] `(mul ~a ~b))
因此,您需要对其进行语法引用,并在所有局部变量后面加上#:

因此,发出宏的宏应为:

(defmacro create-my-macro [macroname]
    `(defmacro ~macroname [a# b#]
       `(mul ~a# ~b#)))

调试提示:macroexpand显示了什么?调试提示:macroexpand显示了什么?是的,你的答案比我的更详细:)是的,你的答案比我的更详细:)