2016-08-01 22 views
0

Wenn ich eine Liste der Lambda-Ausdrücke wie dieses:Aufruf Funktion aus einer Liste von zitierte Lambda-Ausdrücke

CL-USER> (DEFPARAMETER list-of-lambda-exp '(#'(lambda (x) x) #'(lambda (x) (* x x)))) 

Dann wie kann ich auf ein Element dieser Liste FUNCALL?

Die folgende scheint nicht zu funktionieren:

CL-USER> (funcall (FIRST list-of-lambda-exp) 2) 

gibt den Fehler

; Evaluation aborted on #<TYPE-ERROR expected-type: (OR FUNCTION SYMBOL) datum: #'(LAMBDA (X) X)>. 

..., die mit dem Aufruf von functionp auf (first list-of-lambda-exp) konsistent ist. (Das obige gilt auch, wenn ich die #' vor den Lambda-Ausdrücken entferne.)

Wie ändere ich (first list-of-lambda-exp) in eine Funktion? Ich kann mir nicht vorstellen, wie man ein Makro schreibt, das das auch tut. Ich denke, ich mache einen dummen Fehler, kann aber keinen Ausweg finden.

+1

Sie haben die Liste zitiert. Das heißt, es enthält Unterlisten, die zufällig mit dem Symbol 'LAMBDA' beginnen, keine Funktionsobjekte. Sie müssen 'LIST' anstelle von Zitat verwenden. – jkiiski

+0

Zur Erläuterung des @ jkiiski-Punktes ist das ''(#' (lambda (x) x) # '(lambda (x) (* xx))))' die Liste '(quote ((function (lambda (x) x)) (Funktion (Lambda (x) (* xx))))). Das heißt, bedenke, dass '# '(lambda (x) ...)' eine Abkürzung für '(function (lambda (x) ...)' ist.) Du kannst die * list * '(lambda (x)) tatsächlich erzwingen. ..) 'in eine Funktion, also wäre es etwas einfacher, wenn Ihre ursprüngliche Form '' ((lambda (x) ...) (lambda (x) ...))' wäre, ohne die 'Funktion' Teil. –

+0

Danke !! Ich kann damit arbeiten. Aus Neugier: Was wäre, wenn die Liste tatsächlich zitiert wurde? –

Antwort

2

Es gibt zwei Arten von Dingen, die hier passieren. Erstens, denken Sie daran, dass Zitat, die mit ' abgekürzt werden kann, gibt ihr Argument nicht ausgewertet. Dann denken Sie daran, dass # ' eine Abkürzung für Funktion ist. Das heißt, # '(Lambda (x) ...) ist eine Abkürzung für (Funktion (Lambda (x) ...)), nicht nur eine Variante der Liste (Lambda (x) ...). Also:

CL-USER> (quote ((function (lambda (x) x)) (function (lambda (x) (* x x))))) 
;=> (#'(LAMBDA (X) X) #'(LAMBDA (X) (* X X))) 

So entweder Sie mehrere Ebenen in die Liste gehen können die tatsächlichen Lambda-Ausdruck zu erhalten (nur eine Liste, beginnend mit Lambda), die Sie dann coerce in eine Funktion, die Sie aufrufen können:

CL-USER> (let ((fs '(#'(lambda (x) x) #'(lambda (x) (* x x))))) 
      (list (funcall (coerce (second (first fs)) 'function) 42) 
       (funcall (coerce (second (second fs)) 'function) 8))) 
;=> (42 64) 
+0

Danke für die Erklärung !! –

+0

Es ist auch möglich, dass '' list # '(lambda ... 'anstelle von'' (# '(lambda .... ') die bessere Wahl gewesen wäre Ich denke, du wolltest das erwähnen, basierend auf deinem "So, du kannst entweder ...", aber es sieht so aus, als ob dieser Absatz verpasst wurde. – Vatine