【问题标题】:Calling function from a list of quoted lambda expressions从引用的 lambda 表达式列表中调用函数
【发布时间】:2016-08-01 16:55:10
【问题描述】:

如果我有一个这样的 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)>. 

...这与在(first list-of-lambda-exp) 上对functionp 的调用一致。 (即使我删除了 lambda 表达式前面的#',上述情况也是如此。)

如何将(first list-of-lambda-exp) 改成函数?我似乎也无法弄清楚如何编写一个可以做到这一点的宏。我想我犯了一个愚蠢的错误,但找不到出路。

【问题讨论】:

  • 您引用了列表。这意味着它包含恰好以符号LAMBDA 开头的子列表,而不是函数对象。您需要使用LIST 而不是引号。
  • 为了详细说明@jkiiski 的观点,'(#'(lambda (x) x) #'(lambda (x) (* x x)))) 是列表(quote ((function (lambda (x) x)) (function (lambda (x) (* x x)))))。也就是说,请记住#'(lambda (x) ...)(function (lambda (x) ...) 的简写。您实际上可以将 list (lambda (x) ...) 强制转换为一个函数,因此如果您的原始表单是 '((lambda (x) ...) (lambda (x) ...)),而没有 function 部分,它会更容易一些。
  • 谢谢!!我可以处理这个。出于好奇:如果列表确实被引用了怎么办?
  • @RanjitKumaresan 引用了列表,只是 lambda 表达式比您的代码预期的要深一层。

标签: list lambda macros common-lisp


【解决方案1】:

这里发生了两种事情。首先,请记住 quote(可以缩写为 ')返回未计算的参数。然后,请记住 #'function 的简写。也就是说,#'(lambda (x) ...)(function (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)

【讨论】:

  • 谢谢你的解释!!
  • 使用(list #'(lambda ... 而不是'(#'(lambda.... 也可能是更好的选择。我认为您是打算根据您的“因此,您可以...”来提及这一点,但看起来那段似乎被遗漏了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多