在 clisp 中返回 lambda 函数,然后对其求值

发布于 2024-08-13 11:00:53 字数 226 浏览 4 评论 0原文

假设我有这个美妙的函数 foo

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

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

我该怎么做?我一直在谷歌搜索,但似乎无法想出正确的语法。

Suppose I have this wonderful function foo

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

Now, suppose I want to actually use foo and return 42.

How do I do that? I've been scrounging around google and I can't seem to come up with the correct syntax.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心的憧憬 2024-08-20 11:00:53

您想要 FUNCALL 功能:

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

You want the FUNCALL function:

* (defun foo () (lambda () 42))
FOO
* (funcall (foo))
42
时光无声 2024-08-20 11:00:53

这里的相关术语是“Lisp-1”和“Lisp-2”。

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

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

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

您并不真的想做后者,因为这在除非常特殊的情况之外的所有情况下都非常愚蠢,但为了完整起见,这大致就是您的做法:

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

您还应该查看 labelsflet 特殊形式(常用) - 您实际上确实使用后一种方法(这些形式为符号创建临时函数绑定)

。看起来像这样:

(flet ((foo () 
         42))
  (foo))

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

The relevant terms here are "Lisp-1" and "Lisp-2".

Your attempt at calling would work in a Lisp-1 like e.g. Scheme or Clojure.
Common Lisp is a Lisp-2 however which roughly means that variable names and function names are separate.

So, in order to call the function bound to a variable you either need to use the special forms funcall or apply as others have pointed out or set the function value of the symbol foo rather than the variable value.

The former basically takes the variable value of the symbol, assumes/checks that value is a function and then calls the function (with whatever arguments you passed to funcall/apply.

You don't really want to do the latter as that is quite silly in all but very specialised cases, but for completness sake this is roughly how you'd do it:

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

You should also want to look into the labels and flet special forms (which are commonly used) - there you actually do use the latter methods (these forms create a temporary function binding for symbols).

So your problem would there look like this:

(flet ((foo () 
         42))
  (foo))

i.e. here you temporarily bind the function value of the symbol foo to the function returning 42. Within that temporary context you can then call (foo) like regular global functions.

浮生未歇 2024-08-20 11:00:53

您的函数 foo 返回一个 函数。使用 funcall 函数来应用函数到参数,即使参数集为空。

在这里您可以看到 foo 返回 类型的值函数

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

Your function foo returns a function. Use the funcall function to apply a function to arguments, even if the argument set is empty.

Here you can see that foo returns a value of type 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
汐鸠 2024-08-20 11:00:53

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

(apply (foo) nil)

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

Another option besides FUNCALL is APPLY:

(apply (foo) nil)

FUNCALL is the idiomatic way here, but you'll need APPLY when you have a list of parameters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文