首页 > 解决方案 > 为什么 slime 的“包装”与劣质 lisp 不同?

问题描述

我想我对 slime 如何在 Emacs 中运行 lisp 并没有清楚的了解。

假设我有一个包含以下条目的文件:-

(defpackage "TEST"
  (:use "COMMON-LISP"))
(in-package "TEST")
*package*

现在我用任何一个说编译/运行这三个

C-c C-c
C-x C-e

我得到了输出:-

#<PACKAGE "TEST">

但是,如果我现在将缓冲区切换到劣质 lisp 缓冲区并键入

*package*

它给了我输出

#<PACKAGE "COMMON-LISP-USER">

是什么赋予了?使用上面的 slime 命令显然做了一些事情,但它似乎并没有影响 suber-lisp 的主 REPL 循环。

标签: emacslispcommon-lispslime

解决方案


全局特殊变量

由于全局变量使用动态绑定,因此可以重新绑定它们:

CL-USER> *package*
#<The COMMON-LISP-USER package, 117/256 internal, 0/4 external>
CL-USER> (defpackage "TEST"
           (:use "COMMON-LISP"))
#<The TEST package, 0/16 internal, 0/16 external>
CL-USER> (let ((*package* (find-package "TEST")))
           (intern "FOO"))

所以你不需要设置一个全局变量,你可以重新绑定它们。

所以像 SLIME 这样的东西可以重新绑定它们并在反弹变量绑定中执行评估代码:

(let ((*package* (find-package "FOO")))
  (eval (read-from-string some-string-with-code)))

线程局部全局特殊变量

还可以创建线程,这样它们就有自己的“线程本地”全局变量:

(sb-thread:make-thread (lambda (*package*)
                                    ...)
                       :arguments (list *package*))

上面的线程函数会有自己的*package*变量绑定。

IDE 和全局变量

通常人们会希望 IDE 使用当前侦听器线程中的全局变量(每个侦听器线程都应该有自己的全局变量)。

还希望来自编辑器 Lisp 代码缓冲区的评估使用该缓冲区中的包(通常是在顶部定义的包或IN-PACKAGE代码中最上面的包。编辑器也可能能够将包设置为用于当前Lisp 代码缓冲区。

然后 IDE 将在评估期间使用类似上述的内容:重新绑定*package*变量和/或在每个线程中使用具有自己的*package*变量绑定的多个线程。

IDE 和多个劣质 Lisp

通常只有一个劣质的 Lisp,但它可能有多个侦听器。一些 IDE 可能还支持不止一种劣质 Lisp。


推荐阅读