关键字名称空间污染

时间:2016-05-10 06:58:08

标签: common-lisp symbols

我明白了

之间的区别
(defpackage :foo
  (:export :bar))

(defpackage :foo
  (:export #:bar))

是后者不在bar包中实习KEYWORD。我的问题是,这样做是否有意义?毕竟,似乎KEYWORD包的用途是用于实习关键字。

1 个答案:

答案 0 :(得分:4)

包用于维护符号的名称空间。包具有名称,符号具有名称。通常将这些名称作为字符串获取,因此defpackage表单可以使用字符串作为名称:

(defpackage "FOO"
  (:export "BAR"))

某些人不喜欢上面的包描述,因为它暴露了标识符的大小写。通常这不是问题,但是Common Lisp有非标准版本,默认情况下符号可能是小写的。

由于可以使用DEFPACKAGE形式的符号作为名称(并且只有名称很重要),我们可以写:

(defpackage :foo
  (:export :bar))

(defpackage #:foo
  (:export #:bar))

甚至

(defpackage cl-user::foo
  (:export cl-user::bar))


CL-USER 22 > (find-symbol "BAR" "FOO")
FOO:BAR
:EXTERNAL

通常的期望是,垃圾收集器(GC)可能无法删除在包中实现的未引用符号 - Common Lisp标准对此主题没有任何说明,也没有必需的行为。因此,在包中添加新符号通常会使其不断增长。在某些应用程序中,这可能是内存泄漏。

另一个通常的期望是GC会释放未引用的未分隔符号。

如果您不介意关键字包中有批次(无论这意味着什么)符号,那么这不是问题。

LARGE包的典型问题可能是:

  • 实习符号可能未被GCed
  • 使用大包装可能需要一些速度成本

对于典型的DEFPACKAGE形式,我不会指望任何明显的问题,因此出于任何风格原因,人们可能更喜欢一种变体。