Unquoting без пространства имен - PullRequest
2 голосов
/ 29 апреля 2020

Мне нужно заключить в кавычки без пространства имен и объединить его с кавычками. Что-то вроде:

'[a b ~c]

К сожалению, удаление кавычек работает только с syntacti c цитата:

`[a b ~c]

Но затем оно расширяется до

[user/a user/b 7]

Я бы хотел расширить без пространств имен.

Ответы [ 3 ]

3 голосов
/ 29 апреля 2020

То, что было предложено на слабом канале Clojurians, выглядит следующим образом:

Используйте комбинацию «кавычка» для символов, чтобы избавиться от пространств имен:

`[~'a ~'b ~c]

, и это прекрасно работает.

0 голосов
/ 29 апреля 2020

Я знаю, что это, вероятно, не тот ответ, который вы ищете, почему бы не использовать код для создания того, что вы хотите? Зачем все это делать в одном выражении? Например, вы можете использовать

(conj '[a b] c)
0 голосов
/ 29 апреля 2020

В качестве справки, я работал над похожей способностью, которая не требует защитной обработки, такой как ~'a, чтобы каждый символ, который вы хотите sh, оставался неизменным. Это еще не опубликовано, но вот техника:

 ;-----------------------------------------------------------------------------
 (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])
   )

Итак, вместо синтаксической кавычки Clojure (т.е. цитата), вы можете использовать quote-template. Затем используйте unquote или unquote-splicing, чтобы вставить значения в шаблон в кавычках, не добавляя пространство имен к другим символам.

...