如果我有一个像这样的lambda表达式列表:
CL-USER> (DEFPARAMETER list-of-lambda-exp '(#'(lambda (x) x) #'(lambda (x) (* x x))))
然后如何在这个列表的元素上执行操作?
以下似乎无效:
CL-USER> (funcall (FIRST list-of-lambda-exp) 2)
给出错误
; Evaluation aborted on #<TYPE-ERROR expected-type: (OR FUNCTION SYMBOL) datum: #'(LAMBDA (X) X)>.
...这与functionp
上对(first list-of-lambda-exp)
的调用一致。 (即使我删除了lambda表达式前面的#'
,上面也是如此。)
如何将(first list-of-lambda-exp)
更改为函数?我似乎无法弄清楚如何编写一个可以执行此操作的宏。我认为我犯了一个愚蠢的错误,但无法想出办法。
答案 0 :(得分:2)
这里发生了两种事情。首先,请记住引用,可以用&#39; 缩写,返回其参数未评估。然后,请记住#&#39; 是功能的简写。也就是说,#&#39;(lambda(x)...)是(函数(lambda(x)...))的简写,而不仅仅是列表的变体(lambda(x)...)。因此:
CL-USER> (quote ((function (lambda (x) x)) (function (lambda (x) (* x x)))))
;=> (#'(LAMBDA (X) X) #'(LAMBDA (X) (* X X)))
因此,您可以在列表中添加多个级别以获取实际的lambda表达式(只是以 lambda 开头的列表),然后您可以coerce将其转换为您的函数可以打电话:
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)