SBCL:asdf:load-定义字符串常量时系统失败
SBCL: asdf:load-system fails when a string constant is defined
使用 SBCL 时,当 lisp 代码定义字符串常量时,我的系统无法加载通过 ASDF 定义的问题。
这是代码:
constants.lisp
(defconstant A 1.0)
(defconstant B "B")
simple.asd
(defsystem :simple
:components ((:file "constants")))
通过
加载
(asdf:load-system "simple")
我收到以下错误(输出已缩短了一点):
* (asdf:load-system "simple")
; compiling file "/Users/.../constants.lisp"
; compiling (DEFCONSTANT A ...)
; compiling (DEFCONSTANT B ...)
; /Users/.../constants-TMP.fasl written
; compilation finished in 0:00:00.003
debugger invoked on a DEFCONSTANT-UNEQL in thread
#<THREAD "main thread" RUNNING {1002BFEA93}>:
The constant B is being redefined (from "B" to "B")
clisp、ccl、abcl都没有报错。
此外,通过
加载文件
(load "constants.lisp")
工作正常。
我正在使用
SBCL 1.2.14、ASDF 3.1.3、MacOS
感谢任何提示,
奥利弗
为什么字符串常量会失败?
defconstant
的规范告诉我们:
However, the consequences are undefined if an attempt is made to assign a value to the symbol using another operator, or to assign it to a different value using a subsequent defconstant.
这里的重点是不同:根据哪个比较?
The consequences are undefined if there are any bindings of the variable named by name at the time defconstant is executed or if the value is not eql to the value of initial-value.
比较由eql.
完成
SBCL 编译您的文件,然后加载结果(xxx-TMP.fasl
文件),并且对于 that 特定实现,defconstant
形式因此被评估在相同环境中两次。编译器不需要在编译期间实际评估表单(它可以 以某种方式在内部声明 它以便可以内联对常量的进一步使用)但这是一种有效的编译策略。
这里,由于编译环境和加载环境是一样的,而且因为字符串的两次出现not相同(not eq),所以报错。如果你碰巧用相同版本的 SBCL 解释器的另一个实例加载 FASL 文件,它不会给你这个错误。
你能做什么?
不要重新发明轮子,用alexandria:define-constant
,可以指定在哪个测试函数下该值是常量:
(alexandria:define-constant b "B" :test #'string=)
因此,当多次计算时,新的 "B"
值将使用 string=
与现有值进行比较,并且由于它们相等,因此不会执行其他操作。
使用 defvar
,在部署代码之前不要再担心它(在开发过程中通常需要更改常量)。
使用 SBCL 时,当 lisp 代码定义字符串常量时,我的系统无法加载通过 ASDF 定义的问题。 这是代码:
constants.lisp
(defconstant A 1.0)
(defconstant B "B")
simple.asd
(defsystem :simple
:components ((:file "constants")))
通过
加载(asdf:load-system "simple")
我收到以下错误(输出已缩短了一点):
* (asdf:load-system "simple")
; compiling file "/Users/.../constants.lisp"
; compiling (DEFCONSTANT A ...)
; compiling (DEFCONSTANT B ...)
; /Users/.../constants-TMP.fasl written
; compilation finished in 0:00:00.003
debugger invoked on a DEFCONSTANT-UNEQL in thread
#<THREAD "main thread" RUNNING {1002BFEA93}>:
The constant B is being redefined (from "B" to "B")
clisp、ccl、abcl都没有报错。 此外,通过
加载文件(load "constants.lisp")
工作正常。
我正在使用
SBCL 1.2.14、ASDF 3.1.3、MacOS
感谢任何提示,
奥利弗
为什么字符串常量会失败?
defconstant
的规范告诉我们:
However, the consequences are undefined if an attempt is made to assign a value to the symbol using another operator, or to assign it to a different value using a subsequent defconstant.
这里的重点是不同:根据哪个比较?
The consequences are undefined if there are any bindings of the variable named by name at the time defconstant is executed or if the value is not eql to the value of initial-value.
比较由eql.
完成SBCL 编译您的文件,然后加载结果(xxx-TMP.fasl
文件),并且对于 that 特定实现,defconstant
形式因此被评估在相同环境中两次。编译器不需要在编译期间实际评估表单(它可以 以某种方式在内部声明 它以便可以内联对常量的进一步使用)但这是一种有效的编译策略。
这里,由于编译环境和加载环境是一样的,而且因为字符串的两次出现not相同(not eq),所以报错。如果你碰巧用相同版本的 SBCL 解释器的另一个实例加载 FASL 文件,它不会给你这个错误。
你能做什么?
不要重新发明轮子,用
alexandria:define-constant
,可以指定在哪个测试函数下该值是常量:(alexandria:define-constant b "B" :test #'string=)
因此,当多次计算时,新的
"B"
值将使用string=
与现有值进行比较,并且由于它们相等,因此不会执行其他操作。使用
defvar
,在部署代码之前不要再担心它(在开发过程中通常需要更改常量)。