Clojure 宏:在宏中执行代码
Clojure macros : Executing code inside macros
我想创建一个宏,以便我可以在变量本身中添加变量名称。我有这个 Unit
记录。它的 name
成员存储将要创建的变量的名称。
即像 (def a-variable (->Unit 1 1 "a-varible"))
但我不想自己传递变量名。
而且我认为宏可以派上用场。 :)
这是代码:
(defrecord Unit
[value gradient name]
Object
(toString [_]
(str name " : ")))
(defmacro create-unit1 [var-name & body]
`(def ~var-name ~(concat body (list (name var-name)))))
(defmacro create-unit2 [var-name & body]
`(def ~var-name (concat ~@body (list (name '~var-name)))))
但其中 none 正在给我编写代码 :
neurals.core> (macroexpand '(create-unit1 a (->Unit 1.0 0.0)))
(def a ((->Unit 1.0 0.0) "a"))
neurals.core> (macroexpand '(create-unit2 a (->Unit 1.0 0.0)))
(def a (clojure.core/concat
(->Unit 1.0 0.0) (clojure.core/list
(clojure.core/name (quote a)))))
neurals.core>
我想要:
(def a (->Unit 1.0 0.0 (clojure.core/name (quote a))))
在宏中执行 concat
的正确方法是什么?
您可以通过删除 create-unit1
中的 &
来修复您的代码:
(defmacro create-unit1 [var-name body]
`(def ~var-name ~(concat body (list (name var-name)))))
(macroexpand `(create-unit1 a (->Unit 1.0 1.0)))
;; => (def user/a (user/->Unit 1.0 1.0 "a"))
您还可以添加一点语法糖:
(defmacro create-unit1 [var-name body]
`(def ~var-name (~@body ~(name var-name))))
或者,为了使所有内容更加地道:
(defmacro defunit [sym value gradient]
`(def ~sym (->Unit ~value ~gradient ~(name sym))))
(defunit a 1.0 1.0)
;; => #user.Unit{:value 1.0, :gradient 1.0, :name "a"}
我想创建一个宏,以便我可以在变量本身中添加变量名称。我有这个 Unit
记录。它的 name
成员存储将要创建的变量的名称。
即像 (def a-variable (->Unit 1 1 "a-varible"))
但我不想自己传递变量名。
而且我认为宏可以派上用场。 :)
这是代码:
(defrecord Unit
[value gradient name]
Object
(toString [_]
(str name " : ")))
(defmacro create-unit1 [var-name & body]
`(def ~var-name ~(concat body (list (name var-name)))))
(defmacro create-unit2 [var-name & body]
`(def ~var-name (concat ~@body (list (name '~var-name)))))
但其中 none 正在给我编写代码 :
neurals.core> (macroexpand '(create-unit1 a (->Unit 1.0 0.0)))
(def a ((->Unit 1.0 0.0) "a"))
neurals.core> (macroexpand '(create-unit2 a (->Unit 1.0 0.0)))
(def a (clojure.core/concat
(->Unit 1.0 0.0) (clojure.core/list
(clojure.core/name (quote a)))))
neurals.core>
我想要:
(def a (->Unit 1.0 0.0 (clojure.core/name (quote a))))
在宏中执行 concat
的正确方法是什么?
您可以通过删除 create-unit1
中的 &
来修复您的代码:
(defmacro create-unit1 [var-name body]
`(def ~var-name ~(concat body (list (name var-name)))))
(macroexpand `(create-unit1 a (->Unit 1.0 1.0)))
;; => (def user/a (user/->Unit 1.0 1.0 "a"))
您还可以添加一点语法糖:
(defmacro create-unit1 [var-name body]
`(def ~var-name (~@body ~(name var-name))))
或者,为了使所有内容更加地道:
(defmacro defunit [sym value gradient]
`(def ~sym (->Unit ~value ~gradient ~(name sym))))
(defunit a 1.0 1.0)
;; => #user.Unit{:value 1.0, :gradient 1.0, :name "a"}