【问题标题】:How do I use the live-code feature in sbcl?如何使用 sbcl 中的实时代码功能?
【发布时间】:2019-10-17 18:33:00
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

为什么你的例子失败了

在 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 进程的方法。

【讨论】:

猜你喜欢
  • 2012-09-27
  • 2015-02-22
  • 2020-02-27
  • 2012-02-22
  • 1970-01-01
  • 2014-06-02
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
相关资源
最近更新 更多