首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Clojure中嵌套宏

在Clojure中嵌套宏
EN

Stack Overflow用户
提问于 2015-12-19 16:31:56
回答 1查看 132关注 0票数 3

考虑一下这个伪代码:

代码语言:javascript
复制
(defrc name
  "string"
    [a :A]
    [:div a])

其中,defrc将是一个宏,它将扩展到以下内容

代码语言:javascript
复制
(let [a (rum/react (atom :A))]
  (rum/defc name < rum/reactive []
    [:div a]))

其中朗姆酒/defc本身就是一个宏。我想出了下面的代码:

代码语言:javascript
复制
(defmacro defrc
          [name subj bindings & body]
          (let [map-bindings# (apply array-map bindings)
                keys# (keys map-bindings#)
                vals# (vals map-bindings#)
                atomised-vals# (atom-map vals#)]
               `(let ~(vec (interleave keys# (map (fn [v] (list 'rum/react v)) (vals atomised-vals#))))
                     (rum/defc ~name < rum/reactive [] ~@body))))

这几乎奏效了:

代码语言:javascript
复制
(macroexpand-all '(defrc aname
       #_=>   "string"
       #_=>   [a :A]
       #_=>   [:div a]))
(let* [a (rum/react #object[clojure.lang.Atom 0x727ed2e6 {:status :ready, :val nil}])] (rum/defc aname clojure.core/< rum/reactive [] [:div a]))

然而,当使用时,它会导致语法错误:

代码语言:javascript
复制
ERROR: Syntax error at (clojure.core/< rum.core/reactive [] [:div a])

这是因为内部宏没有被扩展吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-20 11:36:40

结果,宏工作正常,但出现了问题,因为<在语法引号中,它被扩展为clojure.core/<,而Rum只是从Rum的源代码中查找引用的<,相关片段:

代码语言:javascript
复制
...(cond
        (and (empty? res) (symbol? x))
          (recur {:name x} next nil)
        (fn-body? xs)        (assoc res :bodies (list xs))
        (every? fn-body? xs) (assoc res :bodies xs)
        (string? x)          (recur (assoc res :doc x) next nil)
        (= '< x)             (recur res next :mixins)
        (= mode :mixins)
          (recur (update-in res [:mixins] (fnil conj []) x) next :mixins)
        :else
          (throw (IllegalArgumentException. (str "Syntax error at " xs))))...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34372904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档