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

Pau*_*han 5 lisp lambda common-lisp

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

[92]> (defun foo () (lambda() 42))
FOO
[93]> (foo)
#<FUNCTION :LAMBDA NIL 42>
[94]> 
Run Code Online (Sandbox Code Playgroud)

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

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

Pil*_*lsy 11

你想要的FUNCALL功能:

* (defun foo () (lambda () 42))
FOO
* (funcall (foo))
42
Run Code Online (Sandbox Code Playgroud)


HD.*_*HD. 6

这里的相关术语是" Lisp-1 "和" Lisp-2 ".

您的调用尝试将在Lisp-1中工作,例如Scheme或Clojure.Common Lisp是一个Lisp-2,但大致意味着变量名和函数名是分开的.

因此,为了调用绑定到变量的函数,您需要使用特殊形式funcall或者apply像其他人指出的那样或设置符号的函数值foo而不是变量值.

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

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

CL-USER> (setf (symbol-function 'foo) (lambda () 42))
#<FUNCTION (LAMBDA ()) {C43DCFD}>
CL-USER> (foo)
42
Run Code Online (Sandbox Code Playgroud)

你也应该要考虑的labelsflet(这是常用的)特殊形式-有你实际使用后者的方法(这些形式创建临时函数符号绑定).

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

(flet ((foo () 
         42))
  (foo))
Run Code Online (Sandbox Code Playgroud)

也就是说,你暂时将符号的函数值绑定foo到返回的函数42.在那个临时的上下文中,你可以(foo)像常规的全局函数一样调用它.