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_Clojurescript - Fatal编程技术网

Clojure 无名称空间的取消引用

Clojure 无名称空间的取消引用,clojure,clojurescript,Clojure,Clojurescript,我需要不带名称空间的引用,并将其与取消引用相结合。比如: '[a b ~c] 不幸的是,取消引用仅适用于语法引用: `[a b ~c] 但随后它扩展到 [user/a user/b 7] 我想在不使用名称空间的情况下进行扩展。clojurians slack channel上的建议如下: 对符号使用“quote unquote”组合以去除名称空间: `[~'a ~'b ~c] 这非常有效。作为参考,我一直在研究一种类似的功能,它不需要像~'a那样对每个希望保持不变的符号进行防御处理。它还

我需要不带名称空间的引用,并将其与取消引用相结合。比如:

'[a b ~c]
不幸的是,取消引用仅适用于语法引用:

`[a b ~c]
但随后它扩展到

[user/a user/b 7]

我想在不使用名称空间的情况下进行扩展。

clojurians slack channel上的建议如下:

对符号使用“quote unquote”组合以去除名称空间:

`[~'a ~'b ~c]

这非常有效。

作为参考,我一直在研究一种类似的功能,它不需要像
~'a
那样对每个希望保持不变的符号进行防御处理。它还没有出版,但这里是技术:

 ;-----------------------------------------------------------------------------
 (defn unquote-form?
   [arg]
   (and (list? arg)
     (= (quote unquote) (first arg))))

 (defn unquote-splicing-form?
   [arg]
   (and (list? arg)
     (= (quote unquote-splicing) (first arg))))

 (defn quote-template-impl
   [form]
   (walk/prewalk
     (fn [item]
       (cond
         (unquote-form? item) (eval (xsecond item))
         (sequential? item) (let [unquoted-vec (apply glue
                                                 (forv [it item]
                                                   (if (unquote-splicing-form? it)
                                                     (eval (xsecond it))
                                                     [it])))
                                  final-result (if (list? item)
                                                 (t/->list unquoted-vec)
                                                 unquoted-vec)]
                              final-result)
         :else item))
     form))

 (defmacro quote-template
   [form]
   (quote-template-impl form))
和单元测试,以显示它的作用:

 ;-----------------------------------------------------------------------------
 (def vec234 [2 3 4])

 (dotest
   (is (td/unquote-form? (quote (unquote (+ 2 3)))))
   (is (td/unquote-splicing-form? (quote (unquote-splicing (+ 2 3)))))

   (is= (td/quote-template {:a 1 :b (unquote (+ 2 3))})
     {:a 1, :b 5})
   (is= (td/quote-template {:a 1 :b (unquote (vec (range 3)))})
     {:a 1, :b [0 1 2]})
   (is= (td/quote-template {:a 1 :b (unquote vec234)})
     {:a 1, :b [2 3 4]})

   (let [result (td/quote-template (list 1 2 (unquote (inc 2)) 4 5))]
     (is (list? result))
     (is= result (quote (1 2 3 4 5))))


   (is= (td/quote-template [1 (unquote-splicing vec234) 5]) ; unqualified name OK here
     [1 2 3 4 5])
   (is= (td/quote-template [1 (unquote-splicing (t/thru 2 4)) 5])
     [1 2 3 4 5])
   (is= (td/quote-template [1 (unquote (t/thru 2 4)) 5])
     [1 [2 3 4] 5])
   )

因此,您可以使用
quote模板
,而不是Clojure的语法引号(即backquote)。然后,使用
unquote
unquote-picting
将值插入到带引号的模板中,而不将名称空间预先添加到其他符号中。

我知道这可能不是您想要的答案,为什么不使用代码来构造您想要的东西呢?为什么要强迫它在一个表达式中完成?例如,你可以使用

(conj '[a b] c)