首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >公共Lisp实现之间不同的":cl“包处理

公共Lisp实现之间不同的":cl“包处理
EN

Stack Overflow用户
提问于 2020-04-23 02:11:12
回答 3查看 216关注 0票数 0

为什么会发生这种行为?另外,这是一个“实现定义的”差异,还是这些REPL中的一个错了?

请考虑这个通用的Lisp代码..。

代码语言:javascript
复制
(defpackage :new)
(in-package new)
(+ 2 2)

在CMUCL中,这将计算为数字4。

在SBCL中,返回一个错误:

代码语言:javascript
复制
; in: + 2
;     (NEW::+ 2 2)
;
; caught COMMON-LISP:STYLE-WARNING:
;   undefined function: NEW::+
;
; compilation unit finished
;   Undefined function:
;     +
;   caught 1 STYLE-WARNING condition

debugger invoked on a COMMON-LISP:UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {1000508083}>:
  The function NEW::+ is undefined.

但是,当将"+“计算为

(cl:+ 2 2)

CMUCL也能处理这个问题。

当我查看HyperSpec时,我找不到一个明确的部分来讨论这个上下文。我能找到的最接近的是:第11.1.2.2节通用LISP用户包。这使我相信SBCL有正确的解释;"NEW“没有继承”公共- Lisp“中的符号,因此整个Common语言在"NEW”内部是不可访问的。但是真的很奇怪,三行文字会扼杀整个语言,所以我还不清楚。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-04-23 03:40:45

您可以指定在defpackage中使用:use继承符号的包,也可以将use-package调用到相同的一端;我通常在defpackage中这样做。我不知道CMUCL在这方面的表现与SBCL不同,但我总是在包中包含(:use :common-lisp)。通用Lisp HyperSpec defpackage文档说:在这里可以看到CMUCL和SBCL之间的区别:

CMUCL

代码语言:javascript
复制
CL-USER> ;; CMUCL
; No value
CL-USER> (defpackage :new)
#<The NEW package, 0/9 internal, 0/2 external>
CL-USER> (package-use-list :new)
(#<The COMMON-LISP package, 0/6 internal, 978/1227 external>)

SBCL

代码语言:javascript
复制
CL-USER> ;; SBCL
; No value
CL-USER> (defpackage :new)
#<PACKAGE "NEW">
CL-USER> (package-use-list :new)
NIL

package-use-list函数显示new包在CMUCL中使用common-lisp,而在SBCL中不使用common-lisp。您可以通过显式useing包来避免此类问题:

代码语言:javascript
复制
CL-USER> (defpackage :new (:use :common-lisp))
#<PACKAGE "NEW">
CL-USER> (package-use-list :new)
(#<PACKAGE "COMMON-LISP">)
CL-USER> (in-package :new)
#<PACKAGE "NEW">
NEW> (+ 2 2)
4

在一个文件中,使用:export表单中的defpackage来导出符号是典型的,但是从new包中的REPL,您也可以定义函数并导出它们的符号,以便在其他包中使用:

代码语言:javascript
复制
NEW> (defun add3 (x) (+ x 3))
ADD3
NEW> (export 'add3)
T

然后返回主工作区common-lisp-user包,并调用use-package来访问新函数:

代码语言:javascript
复制
NEW> (in-package :cl-user)
#<PACKAGE "COMMON-LISP-USER">
CL-USER> (use-package :new)
T
CL-USER> (add3 4)
7
票数 1
EN

Stack Overflow用户

发布于 2020-04-23 03:47:20

它在CL标准中没有定义,当DEFPACKAGE中没有:use子句时,要使用的包。

德帕基

参数:使用设置包名命名的包将继承的包。如果:use未提供,则默认为相同的实现相关值 :use参数to make-package。

SBCL选择不使用任何软件包。

传统上,其他CL实现通常选择使用CL包加上一些扩展包。因此,这样做的意图是,默认情况下,新包对于Lisp编程非常有用,比如包CL-USER

对于可移植代码,需要指定包应该使用的包。通常,defpackagemake-package是要查看的运算符。

票数 3
EN

Stack Overflow用户

发布于 2020-04-23 10:44:35

这是其他答复的增编。

我过去做过的一件事是写一个这样的宏:

代码语言:javascript
复制
(defvar *user-package-use-list*
  (package-use-list (find-package ':common-lisp-user)))

(defmacro define-user-package (name &body options)
  `(defpackage ,name
     (:use ,@(mapcar #'package-name *user-package-use-list*))
     ,@options))

那就用这个

代码语言:javascript
复制
(define-user-package :my-user-package)

定义一个“类似”CL-USER的包,因为它使用所有相同的包,并且它将以一种跨实现的方式来完成这个任务。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61378192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档