在SBCL和CCL实施中使用(make-package 'test) (in-package test)
时,我注意到SBCL需要(cl:defun foo () (...))
或(cl:describe <symbol name here>)
而CCL不需要任何冒号或双冒号来使用内置在符号中。我的理解是,必须使用一个冒号访问外部符号,即使它们是内置的。然而,CCL似乎在这方面的工作方式不同。
这使我对外部符号的使用感到困惑。外部符号是否可以在没有任何冒号的情况下使用,或者CCL只是为了方便而自动使用/导入/继承?
此外,关于符号和包的实现之间是否存在这些小但重要的差异?
答案 0 :(得分:9)
创建软件包时,ANSI CL标准未定义使用的软件包
在某个时间点,SBCL偏离了常规做法,但仍遵循ANSI CL标准。
使用套餐
在其他包中使用包意味着在该包中提供符号。
您可以通过调用函数package-use-list
来获取包的使用列表。
在ANSI Common Lisp标准中未定义,默认情况下打包一个新包使用,如果它使用任何包
。实施中的不同常见做法
现在有两种常见的实践方法:
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中的示例:
* (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中软件包系统的大多数其他差异都围绕着标准的扩展。例子:
分层/嵌套包
整个表单的包前缀(不仅仅是符号)
某些实现提供了更大且不兼容的更改作为选项:
未定义: