如何在Clojure宏扩展时确定

oct*_*bus 2 clojure

我相信我理解在宏扩展期间,宏不能访问函数可以访问的东西,因为扩展在编译时发生.

但是,我很难理解如何在宏扩展时执行检查.

例如:

(defn gen-class [cl-nam]
    (fn [cmd & args]
        (condp = cmd
            :name (name cl-nam))))

(defmacro defnclass [cl-nam]
    `(def ~cl-nam (gen-class '~cl-nam)))
Run Code Online (Sandbox Code Playgroud)

我想检查一下cl-nam不是序列.我想用count来查找它的长度是> 1.

我明白我可以在下面的宏中取消引用println,这样我就可以得到一个扩展时消息.

(defmacro defnclass_info [cl-nam]
    `(do
        ~(println cl-nam)
        (def ~cl-nam (gen-class '~cl-nam))))
Run Code Online (Sandbox Code Playgroud)

但是,我不知道如何检查以查看cl-nam传递的内容.

我正在阅读几本书中的很多Clojure宏描述,并且很难过.谢谢.

kot*_*rak 5

宏实际上只是一个功能.

(defmacro defnclass-info
  [cl-name]
  (when (seq? cl-name)
    (throw (Exception. "cl-name must not be a sequence")))
  `(def ~cl-name (gen-class '~cl-name)))
Run Code Online (Sandbox Code Playgroud)

编辑:还可以切换行为并再次为整个列表递归调用宏.你做什么,取决于你的要求.

(defmacro defnclass-info
  [cl-name]
  (if (seq? cl-name)
    `(do ~@(for [cn cl-name] `(defnclass-info ~cn)))
    `(def ~cl-name (gen-class '~cl-name))))
Run Code Online (Sandbox Code Playgroud)

宏扩展正是"功能"的回归.因此,您可以完全灵活地使用宏参数.