问题描述
我对defun宏的工作方式感到困惑,因为
I'm confused about how defun macro works, because
(defun x () "hello")
将创建函数x,但符号x仍未绑定.
will create function x, but symbol x still will be unbound.
如果我将一些lambda绑定到x,则x将具有一个值,但解释器不会将其视为具有以下形式的函数:
If I'll bind some lambda to x then x will have a value, but it will not be treated by interpreter as function in form like this:
(x)
我认为这与defun应该在全局环境中定义功能这一事实有关,但是我不确定它的确切含义.为什么我不能在当前环境中遮盖它?
I think that it is related to the fact that defun should define function in global environment, but I'm not sure what does it exactly mean. Why can't I shadow it in the current environment?
如果绑定了一些lambda,是否有任何方法可以强制解释器将符号视为函数?例如:
Is there any way to force interpreter treat symbol as function if some lambda was bound to it? For example:
(setq y (lambda () "I want to be a named function"))
(y)
P.S .:我正在使用SBCL.
P.S.: I'm using SBCL.
推荐答案
Common Lisp具有用于函数和值的不同命名空间.
Common Lisp has different namespaces for functions and values.
您可以使用DEFUN
,FLET
,LABELS
和其他一些名称在函数名称空间中定义函数.
You define functions in the function namespace with DEFUN
, FLET
, LABELS
and some others.
如果要获取功能对象作为值,请使用FUNCTION
.
If you want to get a function object as a value, you use FUNCTION
.
(defun foo (x) (1+ x))
(function foo) -> #<the function foo>
或更短:
#'foo -> #<the function foo>
如果要调用函数,则编写(foo 100)
.
If you want to call a function, then you write (foo 100)
.
如果要将函数作为值调用,则需要使用FUNCALL
或APPLY
:
If you want to call the function as a value then you need to use FUNCALL
or APPLY
:
(funcall #'foo 1)
您可以传递函数并调用它们:
You can pass functions around and call them:
(defun bar (f arg)
(funcall f arg arg))
(bar #'+ 2) -> 4
对于DEFUN:
不是(setf (symbol-value 'FOO) (lambda ...))
.
它更像是(setf (symbol-function 'foo) (lambda ...))
.
请注意,这两个名称空间使您可以编写:
Note that the two namespaces enable you to write:
(defun foo (list)
(list list))
(foo '(1 2 3)) -> ((1 2 3))
内置函数LIST
和变量LIST
之间没有冲突.由于我们有两个不同的名称空间,因此我们可以将相同的名称用于两个不同的目的.
There is no conflict between the built-in function LIST
and the variable LIST
. Since we have two different namespaces we can use the same name for two different purposes.
还请注意,在使用局部函数的情况下,不涉及任何符号.命名空间不必与符号绑定.因此,对于局部变量,无法通过符号名称进行功能查找.
Note also that in the case of local functions there is no symbol involved. The namespaces are not necessarily tied to symbols. Thus for local variables a function lookup via a symbol name is not possible.
这篇关于为什么defun与(setq< name>< lambda>)不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!