CL实现之间的包系统有哪些不同之处?

时间:2017-11-09 04:47:45

标签: common-lisp packages symbols

在SBCL和CCL实施中使用(make-package 'test) (in-package test)时,我注意到SBCL需要(cl:defun foo () (...))(cl:describe <symbol name here>)而CCL不需要任何冒号或双冒号来使用内置在符号中。我的理解是,必须使用一个冒号访问外部符号,即使它们是内置的。然而,CCL似乎在这方面的工作方式不同。

这使我对外部符号的使用感到困惑。外部符号是否可以在没有任何冒号的情况下使用,或者CCL只是为了方便而自动使用/导入/继承?

此外,关于符号和包的实现之间是否存在这些小但重要的差异?

1 个答案:

答案 0 :(得分:9)

创建软件包时,ANSI CL标准未定义使用的软件包

在某个时间点,SBCL偏离了常规做法,但仍遵循ANSI CL标准。

使用套餐

在其他包中使用包意味着在该包中提供符号。

您可以通过调用函数package-use-list来获取包的使用列表。

在ANSI Common Lisp标准中未定义,默认情况下打包一个新包使用,如果它使用任何包

实施中的不同常见做法

现在有两种常见的实践方法:

  • 使用 COMMON-LISP和一些特定于实现的包。 CCL这样做。

CCL中的示例:

? (package-use-list (make-package "FOOBAR"))
(#<Package "CCL"> #<Package "COMMON-LISP">)

LispWorks:

CL-USER 17 > (package-use-list (make-package "FOOBAR"))
(#<The COMMON-LISP package, 0/4 internal, 978/1024 external>
 #<The HARLEQUIN-COMMON-LISP package, 0/4 internal, 365/512 external>
 #<The LISPWORKS package, 0/4 internal, 226/256 external>)
  • 使用没有包裹。 SBCL做到了这一点。如果你想要一个新包来使用包COMMON-LISP,那么你必须明确地请求它。

SBCL中的示例:

* (package-use-list (make-package "FOOBAR"))

NIL

ABCL:

CL-USER(1): (package-use-list (make-package "FOOBAR"))
NIL

编写便携式代码

因此,在SBCL中,因此在便携式Common Lisp中,您需要告诉Lisp哪些包应该使用。要获取COMMON-LISP使用且仅包含该包,您需要写:

(make-package "FOO" :use '("COMMON-LISP"))

<强>背景

第一个Common Lisp中的最初想法是,可以在REPL上编写(in-package "FOO"),并且使用合理的默认值创建包,并且一个直接在该包中。默认值通常是语言的包(当时称为“LISP”)和公共扩展的包(例如使用CLOS + MOP,线程......)。

后来Common Lisp被更改,因此IN-PACKAGE没有创建包,并且定义了在创建包时未定义使用哪些包,并且在创建包时不需要使用任何包。然后,SBCL维护人员认为:不是支持通用实践(标准中没有提到),而是在创建包时使用无包装提供更中立且可预测的行为。

其他差异

Common Lisp中软件包系统的大多数其他差异都围绕着标准的扩展。例子:

  • 分层/嵌套包

  • 整个表单的包前缀(不仅仅是符号)

某些实现提供了更大且不兼容的更改作为选项:

  • 所有现有符号的小写和 lowercasing 阅读器。标准默认情况下将符号定义为内部大写。

未定义:

  • 垃圾收集其他未引用但实习的符号