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

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

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

最佳答案

为什么你的例子失败了

当在 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 中输入。

从系统外壳工作

虽然您已经可以将上面的示例用于开发目的,但您可能希望从 shell 与正在运行的 SBCL Lisp 图像进行交互。我不知道该怎么做。对于您的确切示例,您希望让 SBCL 重新加载您已修改的最终文件。简要看一下 SBCL manual似乎没有提供将 lisp 代码通过管道传输到已经运行的 SBCL 进程的方法。

关于common-lisp - 如何使用 sbcl 中的实时代码功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56406426/

相关文章:

common-lisp - 为什么 (equal (copy-<some struct type> <struct type object>) <same struct type object>) nil?

vector - 为什么这个 lisp 向量没有扩展?

csv - Common Lisp 中的快速 CSV 读取

Python REPL : issuing commands in advance to execute after block

lisp - 构建应用程序和调试器

error-handling - SBCL 绕过调试器并打印错误以在其他环境中显示?

list - 返回列表中的特定元素 - LISP

javascript - console.log(...) 和 REPL 模式下的不同输出

clojure - 命名空间未加载到 clojure 基座中

lisp - 未理解的常见 Lisp 错误