Lisp中的变量和符号是否不同?

时间:2011-09-12 08:58:44

标签: lisp

numberp是Lisp中的谓词,(numberp 1)按预期返回T.但是,如果我只在控制台中键入numberp,则会提示变量名称未定义。

这两个有什么区别?

3 个答案:

答案 0 :(得分:12)

这个问题已经有点不对了。

我们在讨论Common Lisp中的不同内容:

  • 符号:这是Lisp中的数据结构。符号是一个带有名称,值,函数,包等的数据对象。

在Common Lisp中,符号可以同时包含值和函数(或宏)。

  • 变量是Lisp代码
  • 中值的标识符

DEFVAR和DEFPARAMETER定义了顶级变量。还有LAMBDA,DEFUN,LET,LET *和其他人定义的局部变量。

(defun foo (i-am-a-variable) ...)

(defparameter *i-am-a-global-variable* ...)
  • 命名的函数是Lisp代码中函数的标识符。命名函数由DEFUN,DEFGENERIC和DEFMETHOD在顶层引入。还有FLET和LABELS定义的本地命名函数。

示例:

(defun i-am-a-function (foo) ...)

(flet ((i-am-a-function (foo) ...)) ...)

要进一步复杂化,函数名称和变量名称是源代码中的符号。

示例:

(type-of (second '(defun foo () nil)))  -->  SYMBOL

让我们看一下函数和变量:

(defun foo ()
  (let ((some-name 100))
    (flet ((some-name (bar) (+ bar 200)))
       (+ some-name (some-name some-name)))))

上面的代码使用了源代码中具有相同符号的变量和函数。由于函数和变量都有自己的命名空间,因此没有冲突。

(+ some-name (some-name some-name))

高于此意味着我们将变量添加到变量函数调用的结果中。

这具有实际效果,您可以执行以下操作:

(defun parent (person) ...)

(defun do-something (parent)
   (parent parent))

您不必担心本地变量名称会影响全局(或本地)函数。它们只是位于不同的名称空间中。

在Scheme中只有一个命名空间,我们必须编写

(define (foo lst) (list 'a lst 'n))

在Common Lisp中我们可以写:

(defun foo (list) (list 'a list 'n))

在Common Lisp中,不需要编写lst而不是list - 因为局部变量list和全局函数list之间没有冲突。 / p>

访问其他命名空间

要获取存储在变量中的函数对象,可以使用FUNCTION

(let ((my-function (function numberp)))
  (funcall my-function 10))

(function foo)可缩短为#'foo

FUNCALL调用一个函数对象。

OTOH,如果你想从函数名称空间中的变量存储一个函数对象,那么只有一种方法:

(setf (symbol-function 'foo) my-function)

对象实际上也是一个函数而不是其他东西(数字,字符串......)也是必要的。否则你会看到一个错误。

这样做的副作用是Common Lisp永远不必检查在(foo bar)中FOO是否真的是一个函数。它不可能不是函数或未定义。

答案 1 :(得分:8)

函数和变量存在于Common Lisp中的不同命名空间中。

因此,当您在预期函数的位置使用名称时(即在正在评估的列表的头部),它会查找具有该名称的函数(或宏)。如果在期望变量的位置使用相同的名称,它将查找具有该名称的变量。

在你的情况下,有一个名为numberp的函数,但不是名为numberp的变量,所以第二种情况会导致错误。

答案 2 :(得分:0)

Scheme(一个Lisp方言,可以这么说)和Common Lisp之间的区别之一是,在Scheme中,有一个名称空间用于变量和函数,而在CL中,有两个单独的名称空间。 因此,在Scheme中,“define”设置这个唯一的名称到值的关联,而在CL中,有值的“define”和函数关联的“defun”。

所以,在CL中你可以:

(define foo ...something...)
(defun foo ...somethingElse...)

让读者感到困惑。

在Scheme中,只有一个:

(define foo something)

如果这个好或坏,过去几乎是宗教纠纷......