Lisp 为什么defun与(setq<;name>;<;lambda>;)不同?

Lisp 为什么defun与(setq<;name>;<;lambda>;)不同?,lisp,common-lisp,sbcl,Lisp,Common Lisp,Sbcl,我对defun宏的工作原理感到困惑,因为 (defun x () "hello") 将创建函数x,但符号x仍将解除绑定 如果我将一些lambda绑定到x,那么x将有一个值,但解释器不会将其视为如下形式的函数: (x) 我认为这与defun应该在全局环境中定义函数这一事实有关,但我不确定它到底是什么意思。为什么我不能在当前环境中对其进行阴影处理 如果某个lambda绑定到符号上,有没有办法强制解释器将其视为函数?例如: (setq y (lambda () "I want to be a na

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

(defun x () "hello")
将创建函数x,但符号x仍将解除绑定

如果我将一些lambda绑定到x,那么x将有一个值,但解释器不会将其视为如下形式的函数:

(x)
我认为这与defun应该在全局环境中定义函数这一事实有关,但我不确定它到底是什么意思。为什么我不能在当前环境中对其进行阴影处理

如果某个lambda绑定到符号上,有没有办法强制解释器将其视为函数?例如:

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

注意:我正在使用SBCL。

Common Lisp为每个符号提供了多个插槽,包括一个值插槽和一个函数插槽。使用语法
(x)
时,common lisp会查找
x
的函数槽绑定。如果要调用值绑定,请使用
funcall
apply


请参见

Common Lisp具有不同的函数和值名称空间

您可以在函数名称空间中使用
DEFUN
FLET
LABELS
和其他一些函数来定义函数

如果要获取函数对象作为值,可以使用
function

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

(function foo)   ->  #<the function foo>
您可以传递函数并调用它们:

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

(bar #'+ 2)  ->  4
在DEFUN的情况下:

它不是
(setf(符号值'FOO)(lambda…)

它更像是
(setf(符号函数'foo)(lambda…)

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

(defun foo (list)
  (list list))

(foo '(1 2 3))  ->  ((1 2 3))
内置函数
LIST
和变量
LIST
之间没有冲突。因为我们有两个不同的名称空间,所以我们可以为两个不同的目的使用相同的名称


还要注意的是,在本地功能的情况下,没有涉及符号。名称空间不一定与符号绑定。因此,对于局部变量,不可能通过符号名查找函数

好极了!我认为perl在$foo、@foo、%foo、foo、@Dmitry上很特别,在POSIX shell中,
$test
,变量与
test
命令/函数无关。
(defun bar (f arg)
  (funcall f arg arg))

(bar #'+ 2)  ->  4
(defun foo (list)
  (list list))

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