Wax 0.1.0: a Rust-like syntax for WebAssembly

I’m happy to announce the first release of Wax, a toolchain that gives WebAssembly a familiar, expression-oriented syntax. It’s written in OCaml and, as of 0.1.0, wax is available on the opam repository:

opam install wax

Why I’m building it. The wasm_of_ocaml runtime is currently about 23k lines of hand-written WebAssembly text (WAT, the official human-readable text representation of WebAssembly). That is a lot of code to maintain in a format that, while readable, is quite verbose: it is built on S-expressions, and everything is explicit, from every variable access down to every type. I’m developing Wax at Tarides to address this, giving that runtime a more concise, type-checked syntax that still compiles to exactly the same bytecode.

The WebAssembly text format spells everything out:

(func $add (param $x i32) (param $y i32) (result i32)
  (i32.add (local.get $x) (local.get $y)))

Wax reads like a programming language:

fn add(x: i32, y: i32) -> i32 {
    x + y;
}

Both compile to identical bytecode. The payoff grows with the program; struct types, nullable references, casts, and loops stay readable where the equivalent WAT sprawls:

type list = { value: i32, next: &?list };

#[export = "sum"]
fn sum(l: &?list) -> i32 {
    let total: i32 = 0;
    while l is &list {
        total += l!.value;
        l = l!.next;
    }
    total;
}

A few highlights:

  • Every direction. All nine conversions between wax, wat, and wasm work, including decompiling an arbitrary .wasm binary back into readable Wax.
  • Full WebAssembly 3.0. Garbage collection, exception handling, tail calls, multiple and 64-bit memories, and SIMD, plus stack switching, threads, wide arithmetic, and branch hints.
  • A real type checker. Errors are caught before any output is produced and reported with source context.
  • A toolchain, not just a compiler. A formatter, a validator, configurable lints, conditional compilation, source maps, and a language server (LSP) with a VS Code extension and tree-sitter grammar.

You can try it in your browser, no install required, on the playground: type Wax and see the WAT and diagnostics live.

This is an early, experimental release. The syntax and the toolchain are still evolving, and I expect rough edges. That is exactly why I’m publishing it now: I’d be very interested in your feedback, whether on the syntax, the ergonomics, missing features, or anything that gets in your way. Bug reports and impressions are all very welcome.

17 Likes