在clisp中返回lambda函数,然后对其进行评估

时间:2009-12-03 09:16:58

标签: lisp lambda common-lisp

假设我有这个奇妙的功能foo

[92]> (defun foo () (lambda() 42))
FOO
[93]> (foo)
#<FUNCTION :LAMBDA NIL 42>
[94]> 

现在,假设我想实际使用 foo并返回42。

我该怎么做?我一直在谷歌周围徘徊,我似乎无法提出正确的语法。

4 个答案:

答案 0 :(得分:11)

您需要FUNCALL功能:

* (defun foo () (lambda () 42))
FOO
* (funcall (foo))
42

答案 1 :(得分:6)

此处的相关术语是“ Lisp-1 ”和“ Lisp-2 ”。

您的调用尝试可以在Lisp-1中使用,例如计划或Clojure。 Common Lisp是一个Lisp-2,但大致意味着变量名和函数名是分开的。

因此,为了调用绑定到变量的函数,您需要使用特殊形式funcallapply,因为其他人已指出或设置符号的函数值{{1而不是变量值。

前者基本上采用符号的变量值,假设/检查该值是一个函数,然后调用该函数(使用您传递给foo / funcall的任何参数。

你真的不想做后者,因为在所有但非常特殊的情况下这是非常愚蠢的,但为了完整起见,这大致是你如何做到的:

apply

您还应该查看CL-USER> (setf (symbol-function 'foo) (lambda () 42)) #<FUNCTION (LAMBDA ()) {C43DCFD}> CL-USER> (foo) 42 labels特殊表单(常用) - 您实际上使用后面的方法(这些表单创建符号的临时函数绑定)。

所以你的问题会是这样的:

flet

即。在这里,您暂时将符号(flet ((foo () 42)) (foo)) function 值绑定到返回的函数42.在该临时上下文中,您可以像常规全局函数一样调用foo

答案 2 :(得分:2)

您的函数foo会返回function。使用funcall函数将函数应用于参数,即使参数集为空。

您可以在此处看到foo返回function类型的值:

CL-USER> (let ((f (foo)))
           (type-of f))
FUNCTION
CL-USER> (let ((f (foo)))
           (funcall f))
42
CL-USER> (type-of (foo))
FUNCTION
CL-USER> (funcall (foo))
42

答案 3 :(得分:2)

除了FUNCALL之外的另一个选项是APPLY:

(apply (foo) nil)

FUNCALL是这里惯用的方式,但是当你有一个参数列表时你需要APPLY。