SLIME 和 Quicklisp 相处得不好

Koz*_*oss 2 emacs sbcl slime quicklisp

我使用 Emacs 作为我的 Common Lisp(准确地说是 SBCL)编辑器,并使用 SLIME。我按照此处的说明设置了 Quicklisp ,并检查它是否在 SLIME之外工作,一切都很好 - 我可以抓取并下载代码,包括它,一切。

现在,我尝试在 Emacs 中使用“编译/加载文件”命令来获取顶部包含以下内容的源文件:

(ql:quickload "priority-queue")

(defpackage :tournament
  (:use :cl :priority-queue))

(in-package :tournament)
Run Code Online (Sandbox Code Playgroud)

现在,再一次,不是在 SLIME 中,这工作得很好。然而,在 SLIME 中,我收到以下形式的错误:

The name "PRIORITY-QUEUE" does not designate any package.
  [Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]
Run Code Online (Sandbox Code Playgroud)

当然,还要加上回溯。我是否遗漏了一些特别的东西?我使用package-installEmacs 安装了 slime,并且在 .emacs 文件中包含以下代码来进行设置:

(setq inferior-lisp-program "/usr/local/bin/sbcl")
(require 'slime)
(slime-setup)
Run Code Online (Sandbox Code Playgroud)

Xac*_*ach 5

发生这种情况是因为编译和加载的时间不同。

编译时,ql:quickload不会评估普通函数调用(如 )。当编译器尝试处理表单时defpackage(这不是普通的函数调用,而是在编译时有副作用的宏),加载“优先级队列”的函数尚未被调用,并且包不可用。

如果您加载文件而不是编译和加载,您将看不到这一点,因为加载会在加载时评估每个表单。

有几个选项可供选择。最简单的是将您的呼叫包装到ql:quickloadin 中eval-when,例如

(eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload "priority-queue"))
Run Code Online (Sandbox Code Playgroud)

我更喜欢为我的项目定义一个系统,无论多么小,所以我会创建一个如下所示的tournament.asd 文件:

(asdf:defsystem #:tournament
  :depends-on (#:priority-queue)
  :serial t
  :components ((:file "tournament.lisp")))
Run Code Online (Sandbox Code Playgroud)

我将其放入 ~/quicklisp/local-projects/tournament/ (以及tournament.lisp)中,并(ql:quickload "tournament")在 repl 中使用来开始并加载它。

我经常使用后一种设置,因此我编写了一个名为Quickproject的 Lisp 程序来为我完成此操作。