Rai*_*wig 12
这个问题已经有点不对了.
我们在讨论Common Lisp中的不同内容:
在Common Lisp中,符号可以同时具有值和函数(或宏).
DEFVAR和DEFPARAMETER定义了顶级变量.还有LAMBDA,DEFUN,LET,LET*等定义的局部变量.
(defun foo (i-am-a-variable) ...)
(defparameter *i-am-a-global-variable* ...)
Run Code Online (Sandbox Code Playgroud)
例:
(defun i-am-a-function (foo) ...)
(flet ((i-am-a-function (foo) ...)) ...)
Run Code Online (Sandbox Code Playgroud)
为了进一步复杂化,函数名称和变量名称是源代码中的符号.
例:
(type-of (second '(defun foo () nil))) --> SYMBOL
Run Code Online (Sandbox Code Playgroud)
我们来看看函数和变量:
(defun foo ()
(let ((some-name 100))
(flet ((some-name (bar) (+ bar 200)))
(+ some-name (some-name some-name)))))
Run Code Online (Sandbox Code Playgroud)
上面的代码使用了一个变量和一个在源代码中具有相同符号的函数.由于函数和变量具有自己的命名空间,因此不存在冲突.
(+ some-name (some-name some-name))
Run Code Online (Sandbox Code Playgroud)
上面意味着我们将变量添加到变量的函数调用结果中.
这具有实际效果,您可以执行以下操作:
(defun parent (person) ...)
(defun do-something (parent)
(parent parent))
Run Code Online (Sandbox Code Playgroud)
您不必担心您的本地变量名称将影响全局(或本地)函数.它们只是位于不同的名称空间中.
在Scheme中只有一个命名空间,我们必须编写
(define (foo lst) (list 'a lst 'n))
Run Code Online (Sandbox Code Playgroud)
在Common Lisp中我们可以写:
(defun foo (list) (list 'a list 'n))
Run Code Online (Sandbox Code Playgroud)
在Common Lisp中,不需要编写lst而不是list- 因为局部变量list和全局函数之间没有冲突list.
访问其他命名空间
要获取存储在变量中的函数对象,可以使用FUNCTION.
(let ((my-function (function numberp)))
(funcall my-function 10))
Run Code Online (Sandbox Code Playgroud)
(function foo)可写得更短#'foo.
FUNCALL 调用一个函数对象.
OTOH,如果你想从函数命名空间中的变量存储一个函数对象,那么只有一种方法:
(setf (symbol-function 'foo) my-function)
Run Code Online (Sandbox Code Playgroud)
对象实际上也是一个函数而不是其他东西(数字,字符串......)也是必要的.否则你会看到一个错误.
这样做的副作用是Common Lisp永远(foo bar)不必检查FOO中是否真的是一个函数.它不可能是函数或未定义的函数.
函数和变量存在于Common Lisp中的不同命名空间中.
因此,当您在预期函数的位置使用名称时(即在正在评估的列表的头部),它会查找具有该名称的函数(或宏).如果在期望变量的位置使用相同的名称,它将查找具有该名称的变量.
在您的情况下,有一个名为numberp的函数,但不是名为numberp的变量,因此第二种情况会导致错误.