Fah*_*tha 5 debian packages sbcl common-lisp slime
我在 Debian 挤压上使用 SBCL 1.0.56,带有 cl-swank/slime 1:20120420-2(Debian 版本号)。这些都是不稳定的当前版本。
我在加载第三方 CL 包时遇到问题。在 Debian 上使用 CL 的文档(实际上是在 Linux 上更通用的 CL 使用文档)是粗略的、矛盾的和过时的,所以我将总结我所知道的。这就是我所在的地方。
Debian 在
/usr/share/common-lisp/source. 在拆分序列的情况下,这是
/usr/share/common-lisp/source/cl-split-sequence。
.asd 文件(这里
/usr/share/common-lisp/source/cl-split-sequence/split-sequence.asd),据我所知,它向 CL 实现提供有关版本和依赖项的说明,看起来像
;;; -*- Lisp -*- mode
(defpackage #:split-sequence-system (:use #:cl #:asdf))
(in-package :split-sequence-system)
(defsystem :split-sequence
:version "20011114.1"
:components ((:file "split-sequence")))
Run Code Online (Sandbox Code Playgroud)
现在,在运行 slime 时,在 REPL 中输入以下两行没有问题
(require :split-sequence)
(split-sequence:SPLIT-SEQUENCE #\, "foo,bar")
Run Code Online (Sandbox Code Playgroud)
该(require :split-sequence)所调用(我认为),航空自卫队的内置副本里SBCL,这大概看split-sequence.asd。这可能是特定于SBCL 的,请参阅Debian 手册第 3 章 -Libraries 中的 Common Lisp。值得注意的是,这个页面与我遇到的任何内容一样有用和详细,经常引用 CLC(Common Lisp 控制器),但 Debian 似乎正在远离这一点。参见
Redesign of Common Lisp Controller,我不完全理解。无论如何,使用 CLC 的记录命令中没有一个对我有用。但是,CLC 在 Debian 上仍然可用。此外,用户邮件列表已死 - 参见The Clc-users Archives
第一次(require :split-sequence)被调用,它被编译,并且(在我的系统上,可能是特定于 Debian 的)结果fasl被放置在
~/.cache/common-lisp/sbcl-1.0.56.0.debian-linux-x86/usr/share/common-lisp/source/cl-split-sequence/split-sequence.fasl
即文件被放置在缓存下的文件系统中,镜像原始源的位置。显而易见的问题是,系统如何知道去哪里寻找包裹?这是我不确定的一件事。看起来搜索路径应该在 中给出
/etc/common-lisp/source-registry.conf.d,它是 ASDF Debian 软件包的一部分,但最接近的是
01-common-lisp-controller.conf,它只是
(:directory #p"/usr/share/common-lisp/systems/")
Run Code Online (Sandbox Code Playgroud)
也许这在某个地方是硬连线的,但我想知道。
无论如何,一旦这个 ASDF 文件在缓存中,它就不会再次编译,但是在 Slime 启动后 REPL 不会看到它,除非require再次编译
。
现在,如果我把线条
(require :split-sequence)
(split-sequence:SPLIT-SEQUENCE #\, "foo,bar")
Run Code Online (Sandbox Code Playgroud)
在一个文件中,例如seq.lisp,并使用 Cc Ck 将其加载到 REPL 中,我收到一个错误和回溯,从
The name "SPLIT-SEQUENCE" does not designate any package.
[Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]
Run Code Online (Sandbox Code Playgroud)
所以我得出结论,这个包没有被正确加载。我尝试过类似的变化
(asdf:oos 'asdf:load-op :split-sequence)
Run Code Online (Sandbox Code Playgroud)
和
(asdf:load-system :split-sequence)
Run Code Online (Sandbox Code Playgroud)
但没有骰子。奇怪的是,假设我们只有这条线
(require :split-sequence)
Run Code Online (Sandbox Code Playgroud)
在一个文件中 -require.lisp为了清楚起见,称之为。然后加载
require.lisp不报错,然后输入
(split-sequence:SPLIT-SEQUENCE #\, "foo,bar")
Run Code Online (Sandbox Code Playgroud)
在 REPL 工作!但是,如果不加载require.lisp,则在 REPL 中无法输入前一行。
那么,总而言之,如何在脚本中成功加载包?我也对上面提到的关于 ASDF 如何找到/usr/share/common-lisp/source/位置的问题感兴趣,但这更像是一个附带问题。
C-c C-k 编译源文件,然后加载编译后的文件。
Lisp 源文件包含定义和调用。文件编译器遍历文件并为其创建代码。但它不执行它。
如果您的文件包含对 的调用REQUIRE,则不会在编译期间执行。如果稍后加载编译的文件,它将被执行。如果文件中的下一个 Lisp 表单正在使用一些在调用 之后可用的包REQUIRE,则它在编译期间不存在,因为REQUIRE尚未执行 - 因此在编译时读取期间出现错误。
基本上有两种解决方案:
REQUIRE在使用所需的功能编译特定文件之前执行所有必要的操作。REQUIRE在编译期间执行语句。这就是EVAL-WHEN :COMPILE-TOPLEVEL告诉 compile 在编译期间执行子表单的地方。#+:sbcl(foo)意味着 (foo) 仅:SBCL在列表中存在符号时才被读取CL:*FEATURES*。使用它是为了让编译器仅在它是 SBCL 时才能看到此代码。
Common Lisp 代码的编译需要更加仔细地准备,因为:
可以在文件编译期间执行 Lisp 代码,从而改变文件编译器的行为。
源代码中使用的包(符号的命名空间)需要为文件编译器的阅读器所知。
| 归档时间: |
|
| 查看次数: |
1133 次 |
| 最近记录: |