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
在Clojure宏中,如何强制自动名称相同?_Clojure - Fatal编程技术网

在Clojure宏中,如何强制自动名称相同?

在Clojure宏中,如何强制自动名称相同?,clojure,Clojure,我正在编写一些Clojure宏,我想在enlive html宏之上使用它们。现在,我需要编写一个宏,在这样使用时: (macroexpand-1 '(def-app [ [:page/not-found [{path :path}] [:path] (content path)] [:page/other-page [{x :x}] [:x] (content x)]])) …将扩展到: (def app ^:dynamic {}) (def-page

我正在编写一些Clojure宏,我想在enlive html宏之上使用它们。现在,我需要编写一个宏,在这样使用时:

(macroexpand-1 '(def-app
  [ [:page/not-found [{path :path}]
      [:path] (content path)]

    [:page/other-page [{x :x}]
      [:x] (content x)]]))
…将扩展到:

(def app ^:dynamic {})

(def-page app
  [:page/not-found [{path :path}]
    [:path] (content path)])

(def-page app
  [:page/other-page [{x :x}]
    [:x] (content x)])
我的尝试是:

(defmacro def-app [pages]
  `(do
    (def app# ^:dynamic {})

    ~@(for [page# pages]
      `(def-page app# ~page#))))
…其扩展到:

(do (def app__3251__auto__ {}) 
    (user/def-page app__3250__auto__ [:page/not-found [{path :path}] [:path] (content path)]) 
    (user/def-page app__3250__auto__ [:page/other-page [{x :x}] [:x] (content x)]))
…除了两件事外,这几乎没什么问题:

  • 名称应用程序扩展为两个不同的名称
  • 结果中缺少^:动态
  • 第二个问题其实不是问题,但我很好奇为什么会发生这种情况


    谢谢

    gensym
    s使用
    #
    创建,仅在创建它们的语法引号中可重用。要重用生成的符号,可以使用显式调用,如下所示:

    (defmacro def-app [pages]
      (let [app (gensym "app")]
        `(do
           (def ~app ^:dynamic {})
           ~@(for [page# pages]
               `(def-page ~app ~page#)))))
    
    这也扩大了:

    (do (def app22770 {}) 
        (user/def-page app22770 [:page/not-found [{path :path}] [:path] (content path)]) 
        (user/def-page app22770 [:page/other-page [{x :x}] [:x] (content x)]))
    
    接下来,
    ^:dynamic
    丢失,因为读取器宏
    ^:
    是在宏扩展编译器阶段之前读取的。将函数或
    与meta一起使用
    生成动态var:

    (defmacro def-app [pages]
      (let [app (gensym "app")]
        `(do
           (def ~(vary-meta app merge {:dynamic true}) {})
           ~@(for [page# pages]
               `(def-page ~app ~page#)))))
    ;; => user/app23239
    
    我们可以看到,生成的var是动态的:

    (meta (var app23239)) 
    ;; => {:dynamic true (...) }