Ranjit Kumaresan
Ranjit Kumaresan

Reputation: 5

Calling function from a list of quoted lambda expressions

If I have a list of lambda expressions like this:

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

Then how do I funcall on an element of this list?

The following doesn't seem to work:

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

gives the error

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

... which is consistent with the call to functionp on (first list-of-lambda-exp). (The above is true even if I remove the #' in front of the lambda expressions.)

How do I change (first list-of-lambda-exp) into a function? I cannot seem to figure out how to write a macro that would do this either. I think I'm making a dumb mistake but can't figure a way out.

Upvotes: 0

Views: 93

Answers (1)

Joshua Taylor
Joshua Taylor

Reputation: 85883

There are two kinds of things happening here. First, remember that quote, which can be abbreviated with ' returns its argument unevaluated. Then, remember that #' is shorthand for function. That is, #'(lambda (x) ...) is shorthand for (function (lambda (x) ...)), not just a variant of the list (lambda (x) ...). Thus:

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

Thus, you can either go multiple levels into the list to get the actual lambda expression (just a list starting with lambda), which you can then coerce into a function that you can call:

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)

Upvotes: 2

Related Questions