2011-01-05 4 views
2

Этот вопрос основан на ограничении this answer.Склеивание unquote для нелитеральных последовательностей

Если у меня есть макрос, который использует сплайсинг конец цитату, как это:

(defmacro instantiate [klass values] 
     `(new ~klass [email protected])) 

Это будет работать только если values является буквальной последовательностью или последующим-состояние.

Если он передается вар держит последовательность, как:

(def v [1 2 3]) 
(macroexpand '(instantiate Person v)) 

Тогда выходной сигнал будет об ошибке, указывающее, что v не является последовательностью.

Даже вызов функции будет интерпретироваться как список:

(defn vf [] [1 2 3]) 
(macroexpand '(instantiate Person (vf))) 
user=>(new Person vf) 

Мой вопрос: есть ли способ использовать сплайсинга конец цитаты в Clojure макросы в этих двух случаях, когда последовательность быть сращены ISN» ли буквальный?

ответ

2

Макросы получают неопровержимые аргументы, поэтому поведение, которое вы видите, так же, как и предполагалось.

Макросы расширяются во время компиляции, а не время выполнения. Значения любых переменных, передаваемых в макрос, могут быть недоступны во время компиляции, поэтому грязные хаки, такие как использование eval, не будут работать в общем случае. Не создавайте макросы, требующие таких трюков.

+0

Поэтому иногда это невозможно, иногда - плохая идея. Благодарю. –

1

сплайсинга котировки сэкономить много времени почти во всех случаях, кроме случаев, когда они не работают, то вам нужно сделать что-то по старинке ...

(defmacro instantiate [klass values] 
    `(new ~klass [email protected])) 

может стать

(defmacro instantiate [klass values] 
    (concat (list 'new klass) (if (seq? values) 
            values 
            (list values)))) 

user=> (macroexpand '(instantiate asdf (1 2 3))) 
(new asdf 1 2 3) 

user=> (macroexpand '(instantiate asdf 1)) 
(new asdf 1) 
+0

Это не решило мою актуальную проблему, так как это было связано с оценкой параметров, но это дало мне представление о том, как действительно работают склейки. благодаря –

Смежные вопросы