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

Byt*_*yte 3 symbols packages common-lisp

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

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

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

Rai*_*wig 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">)
Run Code Online (Sandbox Code Playgroud)

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>)
Run Code Online (Sandbox Code Playgroud)
  • 不使用包裹.SBCL做到了这一点.如果您希望新程序包使用程序包COMMON-LISP,则必须明确请求.

SBCL中的示例:

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

NIL
Run Code Online (Sandbox Code Playgroud)

ABCL:

CL-USER(1): (package-use-list (make-package "FOOBAR"))
NIL
Run Code Online (Sandbox Code Playgroud)

编写可移植代码

因此,在SBCL中,因此在便携式Common Lisp中,您需要告诉Lisp应该使用哪些包.为了让COMMON-LISP使用,只有这个包,你需要写:

(make-package "FOO" :use '("COMMON-LISP"))
Run Code Online (Sandbox Code Playgroud)

背景

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

后来Common Lisp的改变,使IN-PACKAGE没有创建一个包,它定义了在创建包它是不确定的,其使用的软件包,它在创建包使用任何包不是必需的.所述SBCL维护者然后想:与其配套常见的做法(未在标准中提到的),提供的更中性的和可预测的行为使用在创建包没有包.

其他差异

Common Lisp中包装系统的大多数其他差异都是对标准的扩展.例子:

  • 分层/嵌套包

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

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

  • 所有现有符号和小写阅读器的小写字母.标准默认将符号定义为内部大写.

未定义:

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