Common lisp 关键字名称空间污染
我明白Common lisp 关键字名称空间污染,common-lisp,symbols,Common Lisp,Symbols,我明白 (defpackage :foo (:export :bar)) 及 就是后者不会将bar插入关键字包中。我的问题是,这样做有意义吗?看来,关键字包的重点是用来实习关键字。一个包用来维护符号的名称空间。包有名称,符号有名称。通常将这些名称作为字符串获取,因此defpackage表单可以使用字符串作为名称: (defpackage "FOO" (:export "BAR")) 有些人不喜欢上面的包描述,因为它公开了标识符的情况。通常这不是问题,但是有一些非标准版本的Common
(defpackage :foo
(:export :bar))
及
就是后者不会将
bar
插入关键字
包中。我的问题是,这样做有意义吗?看来,关键字
包的重点是用来实习关键字。一个包用来维护符号的名称空间。包有名称,符号有名称。通常将这些名称作为字符串获取,因此defpackage表单可以使用字符串作为名称:
(defpackage "FOO"
(:export "BAR"))
有些人不喜欢上面的包描述,因为它公开了标识符的情况。通常这不是问题,但是有一些非标准版本的Common Lisp,默认情况下符号可以是小写 由于可以在
DEFPACKAGE
表单中使用符号作为名称(并且只有名称是有意义的),我们可以写:
(defpackage :foo
(:export :bar))
或
甚至
(defpackage cl-user::foo
(:export cl-user::bar))
CL-USER 22 > (find-symbol "BAR" "FOO")
FOO:BAR
:EXTERNAL
通常的期望是,包中未引用的符号可能不会被垃圾收集器(GC)删除——公共Lisp标准对此主题只字未提,也没有要求的行为。因此,向包中添加新符号通常会保持包的增长。在某些应用程序中,这可能是内存泄漏
另一个常见的期望是GC将释放未引用和未处理的符号
如果你不介意关键字包中有很多符号(不管这意味着什么),那么这不是问题
大型软件包的典型问题可能是:
- 实习符号不得为GCD
- 使用大型软件包可能会带来一些速度成本
对于典型的
DEFPACKAGE
表单,我不希望出现任何明显的问题,因此无论出于何种风格原因,人们都可能会选择一种变体。“Common Lisp的非标准版本”:即使标准指定了默认情况,也可以对其进行更改,不是吗?假设变量设置为默认值通常是不安全的。实际上,当默认值更改时,Quicklisp中的某些库无法生成。@coredump:ANSI Common Lisp要求(符号名称“cl:defun”)为“defun”,而不是“defun”,也不是“defun”。通用Lisp的一些变体有符号——甚至是标准的CL符号——所有这些符号在内部都是下框的。其思想是简化与外部系统的互操作性。关于GC,标准提到包有内部符号、阴影符号和导出符号。这些列表中的任何一个从任何活动包中引用的符号(即本身不可收集)都不会被垃圾收集。我在defpackage
中使用非预期符号(例如#:symbol
)的主要原因是,无论当前可读表区分大小写模式是什么,它的名称都会被读取,或者特定于实现的case-hack模式,这是字符串无法实现的。与关键字或限定符号或非限定符号相比,我更喜欢非限定符号,因为它不在读取时插入符号,也不在编译文件中存储包名,这也避免了在加载时插入,从而避免了名称冲突。@acelent:例如,Clozure CL垃圾收集未绑定的插入符号。另外:在创建应用程序时,一些常见的Lisp实现可能会清理包并删除未引用的符号。
(defpackage #:foo
(:export #:bar))
(defpackage cl-user::foo
(:export cl-user::bar))
CL-USER 22 > (find-symbol "BAR" "FOO")
FOO:BAR
:EXTERNAL