есть макрос
(...
`(...
,@(operator
'(f1)
...
'(fn)
rest-fns)))
но хочется записать в виде
(...
`(...
,(operator
f1
...
fn
(splice-it rest-fns))))
то есть форма operator вычисляется, но только список rest-fns разбивается на элементы.
Гм... Из формулироваки вопроса совершенно не понятно, что же на самом деле надо.
Попробую привести пример, который как мне кажется (но с большой вероятностью я ошибаюсь) в чём-то схож с такой задачей
(defmacro sample-macro (&rest fns)
(let ((fns2 (loop
for fn in fns
collect (list fn "Hello"))))
`(progn
,@fns2)))(sample-macro print print)что-то типа этого, только вместо if несколько случаев.
http://lisper.ru/apps/format/38
(defmacro prog-nth (nform &body body)
(flet ((split-forms (forms)
(do ((current forms (cdr current))
(first-forms) (last-forms)
(i 1 (1+ i)))
((null current) (values (nreverse first-forms) (nreverse last-forms)))
(if (< i nform)
(push (car current) first-forms)
(push (car current) last-forms)))))
(multiple-value-bind (first-forms last-forms) (split-forms body)
`(progn
,@first-forms
(multiple-value-prog1
,@(if (null last-forms)
'(nil)
last-forms)))))) Ну тогда как-нибудь так:
(defmacro prog-nth (nform &body body)
(flet ((split-forms (forms)
(do ((current forms (cdr current))
(first-forms) (last-forms)
(i 1 (1+ i)))
((null current) (values (nreverse first-forms) (nreverse last-forms)))
(if (< i nform)
(push (car current) first-forms)
(push (car current) last-forms)))))
(multiple-value-bind (first-forms last-forms) (split-forms body)
(let ((last-forms2 (calculate-last-forms last-forms))) `(progn
,@first-forms
(multiple-value-prog1
,@last-forms2))))))тоже самое нужно делать, например, если last-forms nil, то нужно его в список завернуть. вопрос в том, как этого не делать.
> тоже самое нужно делать, например, если last-forms nil,
> то нужно его в список завернуть. вопрос в том, как этого не делать.
Я не понимаю проблемы. В коде макроса может выполняться произвольный код.
>Я не понимаю проблемы.
В том, что если нужно добавить к уже написанному коду (как в первом посте), список, который должен быть разделён, то нужно что-то менять в существующем. Получается, что вместо склевания всего в лист, а потом разрезания, сразу идёт разрезание. Вряд ли проблема серьёзная, но что-то типа values-list, но только в макрорасширение возвращается не список, а несколько значений, примерно так:
(fn a b c (splice-it '(d e)) f) -> (fn a b c d e f)
Насколько я понимаю, то в CL этого сделать нельзя (без оборачивая конструкции в макрос ес-но).
>Получается, что вместо склевания всего в лист, а потом разрезания, сразу идёт разрезание.
в случае со splice-it.