Puppy Scheme

A Scheme compiler targeting WebAssembly.

WASM GCNo runtime garbage collector — uses WebAssembly's built-in GC.
Tiny outputSingle-digit KB binaries. No bloated runtime linked in.
Self-hostingThe compiler compiles itself to WebAssembly.
R7RS librariesdefine-library and import with dead code elimination.

Usage

Compile a Scheme file to WebAssembly:

$ puppyc hello.scm -o hello.wasm
$ wasmtime -W gc hello.wasm

Use a WIT file to define custom component exports:

$ puppyc app.scm --wit app.wit -o app.wasm

The compiler itself is a WASM module. puppyc is a thin wrapper around puppyc.wasm, which can be run directly by any WASI-compatible runtime:

$ wasmtime -W gc puppyc.wasm -- hello.scm -o hello.wasm

Examples

Components

Puppy Scheme components use closures for state. The define-component macro expands to a factory that creates fresh bindings per instance.

0
(define-component counter
  (state (count 0))
  (render
    (html (div (@ (class "counter"))
            (button (@ (on "click" "decrement"))
              "-")
            (span (@ (class "count"))
              ,(number->string count))
            (button (@ (on "click" "increment"))
              "+"))))
  (dispatch event
    (cond ((equal? event "decrement")
           (if (> count 0)
               (set! count (- count 1))))
          ((equal? event "increment")
           (set! count (+ count 1))))))