Sigil 0.17.2

release

Another additive release: a major new capability for the native WebAssembly target, plus two correctness fixes for async programs and the macro system. Existing projects keep building without changes.

Download 0.17.2Get started

Native WebAssembly async suspension

Sigil programs that use the async scheduler (channels, goroutines, anything that suspends and resumes) can now be compiled to the native WebAssembly target and suspend and resume correctly, including across loop iterations. Previously the native-WASM target couldn't yield and resume an async task at all. This is built on Binaryen's Asyncify, with the suspend-set emitted by the compiler itself rather than a hand-maintained list, the minicoro fiber path un-gated for WASM, and a fix so GC roots survive the asyncify rewind across loops. The practical upshot: async Sigil code now works as native WASM, which is the missing piece for running something like the Enclave web client in the browser.

Eval-mode fix for capturing macros

Importing a package that defines a procedural syntax-rules macro which captures an internal definition (for example (sigil match)) no longer crashes under sigil eval. The capture pre-pass recognized only the primitive %lambda as a closure boundary, not the surface lambda that procedural transformers are written with, so a captured definition could be missed and its cell left dangling, producing a GET_CELL error at module load. The compiled path was never affected; this closes the eval-versus-compiled gap. Thanks to Trevor Arjeski, who reported it (issue #8).

Async-port logging no longer recurses

Logging to an async port (stdout, stderr, or an async file) while an exception was unwinding could recurse without bound and take the whole process down, which bit long-running async programs and MCP servers exactly when something had already gone wrong and you most needed the log line. The async write now detects when its scheduler prompt has been unwound past and falls back to a synchronous write instead of aborting into a prompt that no longer exists. Async behavior is otherwise unchanged.