转引自拉姆达列表调用函数表达式
如果我有这样的lambda表达式的列表:转引自拉姆达列表调用函数表达式
CL-USER> (DEFPARAMETER list-of-lambda-exp '(#'(lambda (x) x) #'(lambda (x) (* x x))))
那么我怎么funcall这个列表的元素呢?
下似乎并没有工作:
CL-USER> (funcall (FIRST list-of-lambda-exp) 2)
给出了错误
; Evaluation aborted on #<TYPE-ERROR expected-type: (OR FUNCTION SYMBOL) datum: #'(LAMBDA (X) X)>.
...这是与(first list-of-lambda-exp)
调用functionp
一致。 (即使我删除了lambda表达式前面的#'
,上述情况也是如此。)
如何将(first list-of-lambda-exp)
更改为函数?我似乎无法弄清楚如何写一个可以做到这一点的宏。我认为我犯了一个愚蠢的错误,但无法找到出路。
这里发生了两种事情。首先,记住报价,可与“返回它的参数未计算的缩写。然后,请记住#'是函数的简写。也就是,#'(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表达式(只是一个列表开始拉姆达),然后你可以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)
谢谢你的解释!! –
也可以这样做'(list#'(lambda ...'而不是''(#'(lambda ....')会是更好的选择。认为你打算提到这一点,根据你的“因此,你可以......”,但它看起来好像该段被错过了。 – Vatine
你报的名单。这意味着它包含的子列表恰好以符号“LAMBDA”开头,而不是函数对象。你需要使用'LIST'而不是引号。 – jkiiski
为了阐述@ jkiiski的观点,''(#(lambda(x)x)#'(lambda(x)(* xx))))'是列表'(quote((function(lambda(x) x))(function(lambda(x)(* xx)))))'。也就是说,请记住'#'(lambda(x)...)'是'(函数(lambda(x)...)'的缩写,实际上可以强制* list *'(lambda(x))。 ...)'到一个函数中,所以如果你的原始表单是''((lambda(x)...)(lambda(x)...))',没有'function' 。部分 –
谢谢!!我可以用这个工作,出于好奇:如果什么实际上被引述列表 –