CL 实现之间的包系统有哪些不同?
What are the various differences in package systems between CL implementations?
在 SBCL 和 CCL 实现中使用 (make-package 'test) (in-package test)
后,我注意到 SBCL 需要 (cl:defun foo () (...))
或 (cl:describe <symbol name here>)
而 CCL 不需要任何冒号或双冒号来使用内置-在符号中。我的理解是外部符号必须用一个冒号访问,即使它们是内置的。然而,CCL 在这方面的工作方式似乎有所不同。
这让我对外部符号的使用有些困惑。外部符号是否应该在没有任何冒号的情况下可用,或者 CCL 只是为了方便起见而自动 using/importing/inheriting?
此外,关于符号和包的实现之间是否还有这些细小但重要的差异?
ANSI CL 标准没有定义创建包时使用哪些包
在某个时间点,SBCL 偏离了惯例,但仍遵循 ANSI CL 标准。
使用包
在其他一些包中使用 包意味着在该包中使用它们的符号。
您可以通过调用函数 package-use-list
.
来获取包的 use 列表
它在 ANSI Common Lisp 标准中未定义,它默认打包一个新包 uses 并且如果它 uses any .
实现中的不同常见做法
现在有两种常见的实现方式:
- 使用 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
包 used 并且只有那个包,你需要写:
(make-package "FOO" :use '("COMMON-LISP"))
背景
第一个 Common Lisp 的最初想法是可以在 REPL 中编写 (in-package "FOO")
并且包是使用合理的默认值创建的,并且直接在该包中。默认值通常是语言包(当时称为 "LISP")和通用扩展包(例如 CLOS+MOP、线程等)。
后来更改了Common Lisp,使得IN-PACKAGE不创建包,并且定义在创建包时未定义使用哪些包,并且在创建包时不需要使用任何包。 SBCL 维护者随后想到:与其支持常见做法(标准中未提及),不如提供更中立和可预测的行为,即 在创建包时使用 no package。
其他差异
Common Lisp 中包系统的大多数其他差异都围绕着对标准的扩展。示例:
hierarchical/nested 包
整个形式的包前缀(不仅仅是符号)
一些实现作为选项提供的更大且不兼容的更改:
- 所有现有符号的小写和小写 reader。该标准默认将符号定义为内部大写。
未定义:
- 其他未引用但已驻留的符号的垃圾集合
在 SBCL 和 CCL 实现中使用 (make-package 'test) (in-package test)
后,我注意到 SBCL 需要 (cl:defun foo () (...))
或 (cl:describe <symbol name here>)
而 CCL 不需要任何冒号或双冒号来使用内置-在符号中。我的理解是外部符号必须用一个冒号访问,即使它们是内置的。然而,CCL 在这方面的工作方式似乎有所不同。
这让我对外部符号的使用有些困惑。外部符号是否应该在没有任何冒号的情况下可用,或者 CCL 只是为了方便起见而自动 using/importing/inheriting?
此外,关于符号和包的实现之间是否还有这些细小但重要的差异?
ANSI CL 标准没有定义创建包时使用哪些包
在某个时间点,SBCL 偏离了惯例,但仍遵循 ANSI CL 标准。
使用包
在其他一些包中使用 包意味着在该包中使用它们的符号。
您可以通过调用函数 package-use-list
.
它在 ANSI Common Lisp 标准中未定义,它默认打包一个新包 uses 并且如果它 uses any .
实现中的不同常见做法
现在有两种常见的实现方式:
- 使用 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
包 used 并且只有那个包,你需要写:
(make-package "FOO" :use '("COMMON-LISP"))
背景
第一个 Common Lisp 的最初想法是可以在 REPL 中编写 (in-package "FOO")
并且包是使用合理的默认值创建的,并且直接在该包中。默认值通常是语言包(当时称为 "LISP")和通用扩展包(例如 CLOS+MOP、线程等)。
后来更改了Common Lisp,使得IN-PACKAGE不创建包,并且定义在创建包时未定义使用哪些包,并且在创建包时不需要使用任何包。 SBCL 维护者随后想到:与其支持常见做法(标准中未提及),不如提供更中立和可预测的行为,即 在创建包时使用 no package。
其他差异
Common Lisp 中包系统的大多数其他差异都围绕着对标准的扩展。示例:
hierarchical/nested 包
整个形式的包前缀(不仅仅是符号)
一些实现作为选项提供的更大且不兼容的更改:
- 所有现有符号的小写和小写 reader。该标准默认将符号定义为内部大写。
未定义:
- 其他未引用但已驻留的符号的垃圾集合