为什么 Common Lisp 函数在封闭的 let 之外可见?

Flu*_*lux 3 common-lisp

在Scheme中,下面的函数f在其封闭的外部是不可见的let

(let ()
  (define (f x)
    (+ x 1)))

(f 2)  ; Error.
Run Code Online (Sandbox Code Playgroud)

然而,在 Common Lisp 中,函数f在其封闭的外部是可见的let

(let ()
  (defun f (x)
    (+ x 1)))

(f 2)  ; Returns: 3
Run Code Online (Sandbox Code Playgroud)

上面的 Common Lisp 代码发生了什么?f外面怎么能看得见呢let

Rai*_*wig 6

在Scheme中,define运算符既可用于顶级定义,也可用于内部定义。对于内部定义,这些应该出现在正文的开头,并且它将具有像表单一样的效果letrec*。请参阅 R7RS 中的第 5.3 章。

在 Common Lisp 中defun总是定义一个全局函数。为了定义局部词法函数,Common Lisp 还有另外两个运算符:fletlabelslabels用于递归函数。


raj*_*kar 5

来自 Common Lisp hyperspec:

求值defun导致 function-name 成为 lambda 表达式指定的函数的全局名称

 (lambda lambda-list
   [[declaration* | documentation]]
   (block block-name form*))
Run Code Online (Sandbox Code Playgroud)

在执行的词法环境中进行处理defun

http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm#defun

如果您想要本地定义,请使用fletlabels

在方案的情况下,define是定义它的本地的<body>