2010-04-13 12 views
16

Dire che ho una funzione foo:Come posso unire un elenco al di fuori di una macro in Common Lisp?

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

E poi voglio avvolgerla con una barra delle funzioni:

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

assumere bar è stato poi chiamato in questo modo: (bar 50 1 2 3)

Con questa configurazione, args è un elenco all'interno del corpo della barra che contiene i parametri finali, quindi quando lo passo a foo, invece di ottenere t lui equivalente di (foo 50 100 1 2 3) Io ovviamente ottengo (foo 50 100 '(1 2 3)). Se queste fossero macro, userei `` (foo, x 100, @ args) `nel corpo della barra per unire gli args alla chiamata di funzione. , @ funziona solo all'interno di un elenco tra virgolette, comunque.

Come posso eseguire lo stesso tipo di giunzione all'interno di una funzione normale?

risposta

30

APPLY chiamerà il suo primo argomento con i suoi argomenti successivi e l'ultimo argomento deve essere una lista. Quindi:

(apply #'foo x 100 args) 
+5

che era troppo facile –

+0

+1: mi hai salvato la giornata! O, almeno, mi hai salvato dall'incidere una soluzione molto brutta. – Giorgio

+1

Mi sono imbattuto in questo problema oggi, l'applicazione non funziona perché la "funzione" che volevo applicare è e, che in realtà è una macro! – PuercoPop

0

Questo metodo è lento, ma potrebbe essere quello che stai cercando.

Backquotes, virgole e virgola non sono solo per macro. Possono anche essere usati nelle funzioni se usi anche eval. Di nuovo, questo non è veloce o efficiente. Ad ogni modo, eccolo:

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

Se sei obbligato a usare eval, allora tu non stanno usando un metodo più semplice e chiaro. Il tuo metodo è stato il primo a venirmi in mente, ma volevo qualcosa di meglio. Il mio caso era più complicato, ma applicare con l'append/concatenare l'elenco farà il trucco. –