Jolt:使用Chez Scheme实现的Clojure编译器
摘要
Jolt是一个自托管的Clojure实现,可编译为Scheme(本地使用Chez,通过Gambit支持JavaScript),提供独立二进制文件、真正的并发性以及完整的Clojure语义,无需JVM。
暂无内容
查看缓存全文
缓存时间: 2026/08/12 08:26
# Jolt——Scheme 上的 Clojure
来源:http://jolt-lang.net/
Jolt 是一个自托管的 Clojure 实现,运行在 Scheme 上——原生支持 Chez,通过 Gambit 编译为 JavaScript。无需 JVM,无需构建步骤——大多数可移植的 Clojure 代码无需修改即可运行。
- 编译器用 Clojure 编写,并能编译自身
- 持久化数据、惰性序列、转换器(transducers)、多方法、协议——完整的 Clojure 语义
- 真正的并发:`future`、`agent`、`pmap` 以及基于操作系统线程的 `core.async`
- `jolt build` 生成单个独立二进制文件——运行它无需 Scheme 或 JVM
右侧的终端就是 jolt 本身——由 [Gambit 后端](http://jolt-lang.net/docs/scheme-backends.html) 编译为 JavaScript——在浏览器中实时运行。它运行的是一个[精简构建](http://jolt-lang.net/docs/scheme-backends.html#choosing_how_much_of_the_language_to_build),以保持较小的下载体积,因此这里没有包含正则表达式;如果你尝试使用,它会给出相应提示。
```
jolt via Gambit → JSrepl
user=> (->> (range 10) (filter even?) (map #(* % %)) (reduce +))
120
```
## 为什么选择 Jolt?
#### 自托管编译器
读取 Clojure 代码,将其分析为与宿主无关的中间表示(IR),生成 Scheme 并运行——在 Chez 上原生运行,或通过 Gambit 编译为 JavaScript。编译器用 Clojure 编写,并能编译自身。
#### 独立二进制文件
`jolt build` 会提前编译整个项目——运行时、标准库、应用及其依赖——打包成单个自包含的可执行文件。运行它不需要 Chez、JVM 或源代码。
#### 真正的并发
`future`/`promise`/`agent`/`pmap` 基于共享堆上的操作系统线程运行,与 JVM 语义一致。`core.async` 提供通道和 `go` 块。
#### 完整的数值体系
精确整数和大整数(bignum)、精确比例(`(/ 1 2)` ⇒ `1/2`)以及浮点双精度数。`=` 感知类型类别;`==` 进行值相等性比较。
#### 持久化数据
不可变向量(32 路字典树)、cons 列表,以及具有 Clojure 值语义的 HAMT 映射/集合。瞬态(transient)是真正的可变临时集合。
#### 兼容 Clojure
惰性/无限序列、转换器(transducers)、解构、多方法、协议/记录、元数据、命名空间、运行时 `eval` 以及完整的读取器。
## 快速开始
安装自包含的 `jolt` 二进制文件——它已捆绑运行时、编译器和标准库,因此无需再安装其他任何东西。
```
# 通过 Homebrew 安装
brew install jolt-lang/jolt/jolt
# 或使用安装脚本(Linux / macOS)
curl -sL https://raw.githubusercontent.com/jolt-lang/jolt/main/install | bash
jolt -e '(+ 1 2)' # => 3
```
或者从克隆的仓库运行(需要 [Chez Scheme](https://cisco.github.io/ChezScheme/))——无需构建步骤,引导种子已提交到仓库:
```
git clone --recurse-submodules https://github.com/jolt-lang/jolt.git
cd jolt
bin/jolt -e '(+ 1 2)' # => 3
```
## 用法
### 求值表达式
```
$ bin/jolt -e '(->> (range 10) (filter even?) (map (fn [x] (* x x))) (reduce +))'
# 120
$ bin/jolt -e '(/ 1 2)'
# 1/2
```
### 运行项目
```
bin/jolt run -m myapp.core # 解析 deps.edn,然后运行 -main
bin/jolt -M:test [args] # 运行某个别名下的 :main-opts
bin/jolt path # 打印解析后的源码根目录
```
### 编译独立二进制文件
```
bin/jolt build -m myapp.core -o myapp # 生成单个自包含可执行文件
./myapp arg1 arg2 # 可在任何地方运行;参数会传给 -main
# --opt 用于优化构建,--dev 用于非优化构建
```
### nREPL
```
bin/jolt --nrepl-server # 自动解析 deps.edn,写入 .nrepl-port
# 通过 .nrepl-port 文件连接 CIDER / Calva / Cursive,然后
# 重新定义一个变量,下一次调用即可生效——无需重启
```
针对实时进程进行开发:参见 [REPL 驱动开发](http://jolt-lang.net/docs/repl-driven-development.html)。
阅读[文档](http://jolt-lang.net/docs/getting-started.html),了解安装、编写库和宿主互操作。
## 与 Clojure 的差异
Jolt 以 Clojure 语义为目标,但运行在 Scheme 上,而非 JVM。大多数可移植的 Clojure 代码无需修改即可运行——持久化集合、数值体系、惰性序列、转换器、多方法、协议/记录、原子(atom)、`future`/`agent`/`pmap`、`core.async`、运行时 `eval` 以及完整的读取器,其行为都与 JVM 上一致。真正的差异如下:
| 方面 | 差异 |
| --- | --- |
| Java 互操作 | 没有 JVM,因此没有通用的 Java 互操作、反射或 `gen-class`/`proxy`——提供 `java.*` 的垫片子集,外加 [CFFI](http://jolt-lang.net/docs/native-interop.html) |
| BigDecimal | 不可用(`decimal?` 始终为 false);数值体系其余部分保持一致 |
| 正则表达式 | 由 [irregex](https://github.com/ashinn/irregex) 编译,而非 `java.util.regex`——常见模式可用,部分 Java 特有功能存在差异 |
相似文章
Jolt:在Chez Scheme上运行Clojure
Jolt是一个新的Clojure实现,目标平台为Chez Scheme,旨在提供即插即用的替代方案,具有快速启动和低内存占用,利用Chez的JIT和GC来避免JVM的开销。
Jolt 的程序镜像与可移植 Scheme 后端
Jolt 是一种 Lisp/Scheme 语言,最近新增了两项功能:类似 Common Lisp 和 Smalltalk 风格的程序镜像,用于完整状态序列化与调试;以及一个与 Chez 运行时解耦的可移植 Scheme 后端,实现与架构无关的可移植性。
Jolt 中的 raylib 示例
在 Jolt 中实现的 75 个 raylib 示例,Jolt 是一个基于 Chez Scheme 的原生 Clojure,展示了无需 JVM 即可高效绑定 raylib 的 C API 的 FFI 绑定。
基于Go的Clojure
Glojure是一个开源的、基于Go的Clojure语言解释器,能够无缝访问Go库,并允许嵌入到Go应用程序中。它目前处于早期开发阶段,但已用于业余项目。
Chez Scheme 在 Debian 中的现状
Chez Scheme 10.4.0 在长时间间隔后已上传到 Debian unstable;该软件包已移交至 Debian Scheme Dream Team,交叉编译问题已修复,且未来版本现在要求可重现构建。