gpt4 book ai didi

lisp - 为什么 defun 与 (setq ) 不同?

转载 作者:太空宇宙 更新时间:2023-11-03 18:32:33 24 4
gpt4 key购买 nike

我对 defun 宏的工作原理感到困惑,因为

(defun x () "hello")

将创建函数 x,但符号 x 仍将是未绑定(bind)的。

如果我将一些 lambda 绑定(bind)到 x 那么 x 将有一个值,但它不会被解释器视为这样形式的函数:

(x)

我认为这与 defun 应该在全局环境中定义函数有关,但我不确定它到底是什么意思。为什么我不能在当前环境中隐藏它?

如果某些 lambda 绑定(bind)到它,是否有任何方法可以强制解释器将符号视为函数?例如:

(setq y (lambda () "I want to be a named function"))
(y)

附言:我正在使用 SBCL。

最佳答案

Common Lisp 对函数和值有不同的命名空间。

您可以使用 DEFUNFLETLABELS 和其他一些函数在函数命名空间中定义函数。

如果你想获取一个函数对象作为值,你可以使用FUNCTION

(defun foo (x) (1+ x))

(function foo) -> #<the function foo>

或更短:

#'foo    ->   #<the function foo>

如果你想调用一个函数,那么你写(foo 100)

如果您想将函数作为值调用,则需要使用 FUNCALLAPPLY:

(funcall #'foo 1)

您可以传递函数并调用它们:

(defun bar (f arg)
(funcall f arg arg))

(bar #'+ 2) -> 4

在 DEFUN 的情况下:

它不是(setf (symbol-value 'FOO) (lambda ...))

它更像是 (setf (symbol-function 'foo) (lambda ...))

请注意,这两个命名空间使您能够编写:

(defun foo (list)
(list list))

(foo '(1 2 3)) -> ((1 2 3))

内置函数LIST和变量LIST没有冲突。由于我们有两个不同的 namespace ,因此我们可以为两个不同的目的使用相同的名称。

另请注意,在局部函数的情况下,不涉及符号。 namespace 不一定与符号相关联。因此,对于局部变量,不可能通过符号名称进行函数查找。

关于lisp - 为什么 defun 与 (setq <name> <lambda>) 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11212717/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com