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

Posted

技术标签:

【中文标题】CL 实现之间的包系统都有哪些不同之处?【英文标题】:What are the various differences in package systems between CL implementations?CL 实现之间的包系统有哪些不同之处? 【发布时间】:2018-04-21 23:44:42 【问题描述】:

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

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

另外,关于符号和包的实现之间是否还有这些微小但重要的差异?

【问题讨论】:

【参考方案1】:

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-LISPused 并且只有那个包,您需要编写:

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

背景

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

后来的 Common Lisp 发生了变化,因此 IN-PACKAGE 没有创建包,并且定义了在创建包时未定义使用哪些包,并且在创建包时不需要使用任何包。 SBCL 维护人员随后想到:与其支持常见做法(标准中未提及),不如提供一种更中立且可预测的行为,即在创建包时使用不使用包。

其他区别

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

分层/嵌套包

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

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

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

未定义:

其他未被引用但被保留的符号的垃圾集合

【讨论】:

为什么使用make-package 而不是defpackage 为了便于在开发时重新编译,可能值得看看 uiop 的 define-package。它支持defpackage 所做的所有事情,但在您删除符号并重新编译时不会出错。还有一些额外有用的选项。 @Sylwester,通常有区别:defpackage 不评估它的参数并且它可能有编译时的副作用。

以上是关于CL 实现之间的包系统都有哪些不同之处?的主要内容,如果未能解决你的问题,请参考以下文章

纤亿通谈-单模和多模光纤跳线有哪些不同之处?

在 Android 中的两个 Fragment 之间传递数据都有哪些不同的方式? [复制]

iOS 应用程序和数据库服务器之间都有哪些不同的通信方式?

请问都有哪些好的OA系统管理方法?OA系统又都有哪些主要功能?

呼叫(电话)中都有哪些不同类型的状态

用java来实现单点登录大概都有哪些种方法