【问题标题】: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 只是为了方便而自动使用/导入/继承?

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

【问题讨论】:

    标签: common-lisp packages symbols


    【解决方案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 不评估它的参数并且它可能有编译时的副作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 2017-08-12
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多