如何使用sbcl中的实时代码功能?

时间:2019-06-01 11:46:04

标签: common-lisp read-eval-print-loop sbcl

我正在尝试进行实时编码以在Lisp中工作。我有文件t.cl,其中仅包含以下行:(loop(write(- 2 1)))。现在,当我使用sbcl --load t.cl --eval '(quit)'在bash中运行文件时,它将运行该行,但是当我尝试在另一个终端中编辑该文件并在运行时将其保存时,没有任何变化..

1 个答案:

答案 0 :(得分:0)

您的示例为何失败

在shell中运行sbcl --load t.cl --eval '(quit)'时,其作用是在进程中启动SBCL Lisp映像,编译文件并运行它。然后,您修改文件并将其保存到磁盘。对于已经运行的SBCL进程,该最后一个动作无关紧要,该进程已经编译了先前的文件。 SBCL在您要求时读取文件一次,一旦它运行了编译的指令,除非您明确要求,否则没有理由再次查看该文件。

使用Emacs + SLIME的“实时”示例

为了对正在运行的程序执行“实时”更改,您必须与已经运行的Lisp映像进行交互。使用Emacs + Slime可以轻松做到这一点。例如,您可以具有如下循环:

(defun foo (x) (+ x 3))

(dotimes (it 20)
  (format t "~A~%" (foo it))
  (sleep 1))

,然后在REPL中使用新定义重新编译foo

(defun foo (x) (+ x 100))

另一个线程将用于重新编译该函数。编译完成后,新函数将用于以后的调用。 REPL中的输出将如下所示:

3
4
5
CL-USER> (defun foo (x) (+ x 100))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN
FOO
103
104
105
...

这也适用于从另一个文件编译的foo的新定义,而不是直接在REPL中输入。

从系统外壳工作

虽然您已经可以将以上示例用于开发目的,但是您可能希望与外壳中正在运行的SBCL Lisp映像进行交互。我不知道该怎么做。对于您的确切示例,您想让SBCL重新加载您已修改的最终文件。简要了解SBCL manual似乎并没有提供将Lisp代码传递到已经运行的SBCL进程的方法。