Как вставить в список вне макроса в Common Lisp?

Скажем, у меня есть функция foo:

(defun foo (x y &rest args) ...)

И позже я хочу обернуть его функциональной панелью:

(defun bar (x &rest args) (foo x 100 args))

Предположим, что бар тогда назывался так: (bar 50 1 2 3)

При такой настройке args представляет собой список в теле bar, который содержит конечные параметры, поэтому, когда я передаю его в foo, вместо получения эквивалента (foo 50 100 1 2 3) я, конечно же, получаю (foo 50 100 '(1 2 3)). Если бы это были макросы, я бы использовал ``(foo ,x 100 ,@args)` внутри тела bar для соединения аргументов с вызовом функции. Однако ,@ работает только внутри списка, заключенного в обратные кавычки.

Как я могу сделать такое же соединение в обычной функции?


person derefed    schedule 13.04.2010    source источник


Ответы (2)


APPLY вызовет свой первый аргумент с последующими аргументами, а последний аргумент должен быть списком. Так:

(apply #'foo x 100 args)
person Xach    schedule 13.04.2010
comment
+1: Вы спасли мой день! Или, по крайней мере, вы спасли меня от взлома очень уродливого решения. - person Giorgio; 17.05.2013
comment
Я столкнулся с этой проблемой сегодня, применение не работает, потому что функция, которую я хотел применить, это и, которая на самом деле является макросом! - person PuercoPop; 09.06.2013

Этот метод медленный, но это может быть то, что вы ищете.

Обратные кавычки, запятые и запятые используются не только для макросов. Их также можно использовать в функциях, если вы также используете eval. Опять же, это не быстро и не эффективно. Во всяком случае, вот:

(defun bar (x &rest args)
  (eval `(foo ,x 100 ,@args)))
person Daniel Cussen    schedule 24.03.2011
comment
Если вы вынуждены использовать eval, значит, вы не используете более простой и понятный метод. Ваш метод был первым, что пришло мне в голову, но хотелось чего-то получше. Мой случай был более сложным, но применить с помощью списка append/concatenate 'сделает свое дело. - person Luka Ramishvili; 21.02.2012