从引用的lambda表达式列表中调用函数

时间:2016-08-01 16:55:11

标签: list lambda macros common-lisp

如果我有一个像这样的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)更改为函数?我似乎无法弄清楚如何编写一个可以执行此操作的宏。我认为我犯了一个愚蠢的错误,但无法想出办法。

1 个答案:

答案 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)