← 返回日报
精读 预计 2 分钟

A pure scheme web programming tool

摘要

Goeteia 将整个 Scheme 编译器内嵌在浏览器,体积约 70 KB gzipped,首次加载后缓存,每次运行源代码只需约 15 ms 即可重新编译。编译器自身使用它编译的 Scheme 子集自托管,输出字节完全相同,CI 中每改动都校验 fixpoint 一致性。运行时使用原生 Wasm GC 对象(Fixnum 为 unboxed i31ref,pair 和 record 为 GC structs),eq? 直接 ref.eq,无 JS 阴影堆。支持 hygienic macros(syntax-rules 与 procedural syntax-case)、真实闭包与尾调用、call/cc 与 dynamic-wind(利用 Wasm 异常处理提案)。前端提供 reactive web 栈(web sx 模板 + fine-grained signals + web html 渲染)、3D WebGL(web three 与 web gl)、以及 Scheme-to-Scheme RPC(Igropyr 后端请求回复为 s-expression,使用 web fetch / web ws / web sse / web json)。库采用 R6RS-style library 系统,依赖优先导出为建议。快速启动:任何支持 Wasm GC 与尾调用的引擎(Node 22+、Chrome/Firefox/Safari、wasmtime)均可运行;从源代码引导需 Chez Scheme。

荐读理由

用Wasm GC编译Scheme到浏览器,live 15ms重新编译+自托管字节级可复现,能直接抄到我AI工程项目里跑生产级WASM GC代码;reactive sx+WebGL shaders+web js FFI是真实非炒作的技术变化;提供AI系统领域的少量高价值信息,不在重要变化上掉队

原文

Everything beside this is live rendered by Goeteia. The Scheme below is compiled to WebAssembly in your browser and mounted live.

booting the compiler…

No server compiles this — the page carries the whole compiler (goeteia.wasm, ~70 KB gzipped, cached after first load), and each Run recompiles the source above in ~15 ms.

What's inside

Self-hosting, to the byte

The compiler is written in the Scheme subset it compiles. The self-hosted build recompiles itself and the output is byte-identical — the fixpoint is checked in CI fashion on every change, and every test runs through both stages.

Native Wasm GC objects

Fixnums are unboxed i31refs, pairs and records are GC structs, eq? is one ref.eq. No shadow heap in JavaScript: the host supplies two byte-stream imports and nothing else.

Hygienic macros

syntax-rules and procedural syntax-case with fenders, nested ellipses and datum->syntax, running in a compile-time interpreter with hygiene by renaming.

Real closures, real tail calls

Typed function references with a fast per-arity entry and a generic entry per closure — variadic procedures and apply are cheap, and every tail call is a return_call. A 100M-iteration loop runs in constant stack, in ~150ms.

call/cc & dynamic-wind

Escape continuations ride the Wasm exception-handling proposal: capture is O(1), the normal path costs one try block, and winders unwind inner-to-outer on the way out.

A reactive web stack

(web sx) templates over fine-grained (web reactive) signals, an (web html) renderer, and a (web js) FFI that reaches straight into the host — this page is built with it.

3D and WebGL

(web three) builds reactive Three.js scenes the way sx builds DOM; (web gl) drives raw WebGL through a command buffer — one bridge call per frame — with shaders written as s-expressions in (web glsl). The title above is exactly this: dot-matrix glyphs, a vertex shader, one draw call.

Scheme-to-Scheme, no codec

When the backend is also Scheme (Igropyr), requests and replies are s-expressions — (rpc "/rpc" '(add 1 2 1/2)) comes back (ok 7/2), the exact ratio intact. (web fetch) makes it direct-style over Wasm JSPI; (web ws) / (web sse) push datum streams; (web json) handles everyone else.

Libraries

R6RS-style (library ...) files with (import (math utils)) resolution, dependencies first; exports are advisory because unused code is pruned anyway.

Quick start

$ git clone https://github.com/guenchi/Goeteia
$ cd Goeteia
$ ./run-tests.sh                # every test, both compiler stages
$ ./build-self.sh               # rebuild the compiler with itself

$ echo '(define (fact n) (if (zero? n) 1 (* n (fact (- n 1)))))
(fact 20)' > fact.ss
$ node rt/compile.mjs goeteia.wasm fact.ss fact.wasm
$ node rt/run.mjs fact.wasm
2432902008176640000

Compiled modules run on any engine with Wasm GC and tail calls: Node 22+, current Chrome / Firefox / Safari, wasmtime. Bootstrapping from source needs Chez Scheme; the checked-in compiler wasm works without it.

Hacker News · 98 赞 · 22 评 讨论 → 阅读原文 →

这条对你有帮助吗?