2010-04-13 6 views
16

Say mam foo funkcję:Jak splajnuować listę poza makrem w Common Lisp?

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

I później chcą zawinąć go w pasku funkcji:

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

Załóżmy bar był wówczas nazywany tak: (bar 50 1 2 3)

Przy tym ustawieniu args jest listą wewnątrz bryły paska, która przechowuje parametry końcowe, więc kiedy przekazuję ją do foo, zamiast odbierania t on odpowiada (foo 50 100 1 2 3) I oczywiście uzyskać (foo 50 100 '(1 2 3)). Gdyby były to makra, użyłbym `` (foo, x 100, @ args) `w ciele paska, aby splicować args do wywołania funkcji. @ działa tylko na liście cytowanej za pomocą zwrotów.

Jak mogę zrobić ten sam rodzaj łączenia w ramach zwykłej funkcji?

Odpowiedz

30

APPLY wywoła pierwszy argument z jego kolejnymi argumentami, a ostatni argument musi być listą. A więc:

(apply #'foo x 100 args) 
+5

To było zbyt łatwe –

+0

+1: Uratowałeś mi dzień! A przynajmniej uratowałeś mnie przed hackowaniem bardzo brzydkiego rozwiązania. – Giorgio

+1

Wpadłem dzisiaj na ten problem, zgłoszenie nie działa, ponieważ "funkcja", którą chciałem zastosować, jest i, co w rzeczywistości jest makrem! – PuercoPop

0

Ta metoda jest powolna, ale może być tym, czego szukasz.

Podanie, przecinki i przecinki to nie tylko makra. Mogą być również używane w funkcjach, jeśli używasz również eval. Ponownie, nie jest to szybkie ani efektywne. W każdym razie tutaj:

(defun bar (x &rest args) 
    (eval `(foo ,x 100 ,@args))) 
+1

Jeśli jesteś zmuszony do korzystania z eval, to nie używają łatwiejszej i jaśniejszej metody. Twoja metoda była pierwsza, która przyszła mi do głowy, ale chciałem czegoś lepszego. Moja sprawa była bardziej skomplikowana, ale zastosuj ją z listą append/concatenate. –