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