Ble*_*ers 16 lisp elisp common-lisp
在Python中,我们有del删除变量的语句.
例如:
a = 1
del a
Run Code Online (Sandbox Code Playgroud)
在Lisp中这相当于什么?
(setq foo 1)
;; (del foo) ?
Run Code Online (Sandbox Code Playgroud)
Rai*_*wig 24
在Common Lisp中.
对于符号作为变量:
CL-USER 7 > (setf foo 42)
42
CL-USER 8 > foo
42
CL-USER 9 > (makunbound 'foo)
FOO
CL-USER 10 > foo
Error: The variable FOO is unbound.
Run Code Online (Sandbox Code Playgroud)
看到:
Python名称驻留在名称空间中,del从名称空间中删除名称.Common Lisp有不同的设计,对编译高效代码更加同情.
在常见的lisp中,我们有两种"变量".词汇变量占其中的大多数.词汇变量类似于C local.在运行时,词法变量通常被实现为一点存储(在堆栈上)并且仅保留与其名称的关联以用于调试目的.在python使用的意义上谈论删除词法变量并没有任何意义,因为与词汇变量存在的python命名空间最接近的类比是词法范围,而纯粹是规范和编译器/评估者使用的抽象.
CL中的第二种变量"变量"是"全局"符号.符号是非常丰富的数据结构,比python中的标签更丰富.它们可以包含大量与它们相关的信息,值,打印名称,"主页"包,函数以及存储在属性列表中的其他任意信息.其中大多数是可选的.当您在源代码中使用名称时,例如(+ X 3),名称X通常表示词法符号.但是,如果编译器/评估者认为你不想要"全局"符号的值,那就失败了.即你有效地写了(符号值'X)而不是X.由于几十年前的拼写错误,编程惯例和其他事情,编译器开始抱怨在没有声明符号的符号的情况下引用"全局"符号本打算是一个"全球化的".该声明被称为"特殊".是的,这是一个愚蠢的命名法.更糟糕的是,特殊变量不仅仅是全局变量,它们还有一个非常有用的功能,称为动态绑定 - 但这是另一个主题.
特殊的符号几乎总是使用defvar,defparameter或defconstant声明.有一个几乎强制性的编码约定,它们拼写唯一,即*X*而不是X.一些编译器和大多数开发人员会抱怨如果你偏离该约定.
好.所以现在我们可以回到del.特殊变量用符号表示; 这类似于python变量用名称表示的方式.在python中,名称在当前名称空间中查找.在Common Lisp中,它们会在当前包中查找.但是当查找发生时有所不同.在python中它是在运行时完成的,因为名称可以在程序运行时动态添加和删除.在Common Lisp中,在编译程序之前从文件中读取程序时会查找名称.(有例外,但我们不要考虑那些.)
您可以从包中删除符号(请参阅unintern).但这是一种罕见的事情,可能会让你的大脑受到伤害.这是一个简单的操作,但它的边缘令人困惑,因为包装系统有一小部分聪明的功能,虽然非常有帮助,但需要花费一些力气才能舒服.因此,从某种意义上说,对你的问题的简短回答是,对于全局符号,unintern是类似的操作.但如果您使用它,您可能会做一些非常特殊的事情(可能是错误的).