Clojure 的 REPL 如何维护状态?

How does Clojure's REPL maintain state?

网上看到Clojure使用ASM库生成JVM Bytecode,还看到Clojure有REPL

我假设 REPL 执行的每一行代码都使用 ASM 编译成 Java class,然后加载 class 以执行代码。如果是这种情况,那么每一行都会导致生成一个新的 class 文件,所以我不确定在一行上声明的局部变量如何与 REPL 中的后续行共享。

有人知道 Clojure 的 REPL 是如何工作的吗?我尝试阅读 Clojure 源代码,但我对 Clojure 了解不多。

一次编译的不是“每一行”,而是“每一表”。

在 REPL 中,你总是在某个命名空间中。您可以使用 in-ns 更改 REPL 的当前命名空间。在每个名称空间中,符号(松散地称为“名称”)和 Var(松散地称为包含不可变值的容器)之间存在绑定。命名空间的“状态”在该命名空间的绑定中。

例如,如果您在当前命名空间中评估表单 (def a 17),这将为指向 a 的名称创建一个新的(如果它尚不存在)绑定=13=] 包含值 17。现在,您稍后可以在同一个命名空间中评估表单 (+ a 25) 。这将在命名空间中获取 a 的值并将其添加到 25 到 return 42.

以上是命名空间本地的符号。这些符号可用于在该名称空间中评估的所有形式。 (它们也可以从其他命名空间访问,但我暂时不考虑)。

您可以看看 https://clojure.org/reference/evaluation if you have not already. The article at https://clojure.org/reference/vars 也可能会有帮助。