为什么 Common Lisp 函数在封闭的 let 之外可见?
Why are Common Lisp functions visible outside an enclosing let?
在 Scheme 中,下面的函数 f
在其封闭 let
:
之外是不可见的
(let ()
(define (f x)
(+ x 1)))
(f 2) ; Error.
然而,在 Common Lisp 中,函数 f
在其封闭 let
:
之外是可见的
(let ()
(defun f (x)
(+ x 1)))
(f 2) ; Returns: 3
上面的 Common Lisp 代码是怎么回事? f
如何在 let
之外可见?
来自普通的 lisp hyperspec:
计算 defun
导致函数名成为 lambda 表达式指定的函数的全局名称
(lambda lambda-list
[[declaration* | documentation]]
(block block-name form*))
在执行 defun
的词法环境中处理。
http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm#defun
如果您想要本地定义,请使用 flet
或 labels
。
在方案的情况下,define
在定义它的 <body>
中是局部的。
在 Scheme 中,define
运算符可用于顶级定义 和 用于内部定义。对于内部定义,这些应该出现在 body 的开头,它的效果类似于 letrec*
形式。请参阅 R7RS 中的第 5.3 章。
在 Common Lisp 中 defun
总是定义一个全局函数。为了定义局部词法函数,Common Lisp 还有两个其他运算符:flet
和 labels
。 labels
用于递归函数。
在 Scheme 中,下面的函数 f
在其封闭 let
:
(let ()
(define (f x)
(+ x 1)))
(f 2) ; Error.
然而,在 Common Lisp 中,函数 f
在其封闭 let
:
(let ()
(defun f (x)
(+ x 1)))
(f 2) ; Returns: 3
上面的 Common Lisp 代码是怎么回事? f
如何在 let
之外可见?
来自普通的 lisp hyperspec:
计算 defun
导致函数名成为 lambda 表达式指定的函数的全局名称
(lambda lambda-list
[[declaration* | documentation]]
(block block-name form*))
在执行 defun
的词法环境中处理。
http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm#defun
如果您想要本地定义,请使用 flet
或 labels
。
在方案的情况下,define
在定义它的 <body>
中是局部的。
在 Scheme 中,define
运算符可用于顶级定义 和 用于内部定义。对于内部定义,这些应该出现在 body 的开头,它的效果类似于 letrec*
形式。请参阅 R7RS 中的第 5.3 章。
在 Common Lisp 中 defun
总是定义一个全局函数。为了定义局部词法函数,Common Lisp 还有两个其他运算符:flet
和 labels
。 labels
用于递归函数。