# hoot

Published articles for hoot.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## wastrel milestone: full hoot support, with generational gc as a treat

DevFeed: [wastrel milestone: full hoot support, with generational gc as a treat](<https://devfeed.tech/articles/wastrel-milestone-full-hoot-support-with-generational-gc-as-a-treat-35036.md>)

Original publisher: [Read original article](<https://wingolog.org/archives/2026/04/09/wastrel-milestone-full-hoot-support-with-generational-gc-as-a-treat>)

Author: Andy Wingo

Published: 2026-04-09T13:48:04Z

Content type: article

Language: en

Sources: [wingolog](<https://devfeed.tech/sources/wingolog.md>)

Topics: [WebAssembly](<https://devfeed.tech/topics/web-assembly.md>), [scheme](<https://devfeed.tech/topics/scheme.md>), [toolchain](<https://devfeed.tech/topics/toolchain.md>), [gcc](<https://devfeed.tech/topics/gcc.md>)

Tags: [binaries](<https://devfeed.tech/tags/binaries.md>), [garbage-collection](<https://devfeed.tech/tags/garbage-collection.md>), [gc](<https://devfeed.tech/tags/gc.md>), [gcc](<https://devfeed.tech/tags/gcc.md>), [hoot](<https://devfeed.tech/tags/hoot.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [repl](<https://devfeed.tech/tags/repl.md>), [scheme](<https://devfeed.tech/tags/scheme.md>), [spidermonkey](<https://devfeed.tech/tags/spidermonkey.md>), [toolchain](<https://devfeed.tech/tags/toolchain.md>), [treats](<https://devfeed.tech/tags/treats.md>), [v8](<https://devfeed.tech/tags/v8.md>), [wasm](<https://devfeed.tech/tags/wasm.md>), [wastrel](<https://devfeed.tech/tags/wastrel.md>), [web](<https://devfeed.tech/tags/web.md>), [webassembly](<https://devfeed.tech/tags/webassembly.md>)

### AI overview

The article describes a Wastrel milestone: compiling WebAssembly files produced by the Hoot Scheme toolchain into native binaries, including a console-based read-eval-print loop. It covers the build process, runtime modules, binary size, dependencies, and initial performance observations.

### Source excerpt

Hear ye, hear ye: Wastrel and Hoot means REPL! Which is to say, Wastrel can now make native binaries out of WebAssembly files as produced by the Hoot Scheme toolchain, up to and including a full read-eval-print loop. Like the REPL on the Hoot web page, but instead of requiring a browser, you can just run it on your console. Amazing stuff! try it at home First, we need the latest Hoot. Build it from source, then compile a simple REPL: echo '(import (hoot repl)) (spawn-repl)' > repl.scm ./pre-inst-env hoot compile -fruntime-modules -o repl.wasm repl.scm This takes about a minute. The resulting wasm file has a pretty full standard library including a full macro expander and evaluator. Normally Hoot would do some aggressive tree-shaking to discard any definitions not used by the program, but with a REPL we don't know what we might need. So, we pass -fruntime-modules to instruct Hoot to record all modules and their bindings in a central registry, so they can be looked up at run-time. This results in a 6.6 MB Wasm file; with tree-shaking we would have been at 1.2 MB. Next, build Wastrel from source, and compile our new repl.wasm: wastrel compile -o repl repl.wasm This takes about 5 minutes on my machine: about 3 minutes to generate all the C, about 6.6MLOC all in all, split into a couple hundred files of about 30KLOC each, and then 2 minutes to compile with GCC and link-time optimization (parallelised over 32 cores in my case). I have some ideas to golf the first part down a bit, but the the GCC side will resist improvements. Finally, the moment of truth: $ ./repl Hoot 0.8.0 Enter `,help' for help. (hoot user)> "hello, world!" => "hello, world!" (hoot user)> statics When I first got the REPL working last week, I gasped out loud: it's alive, it's alive!!! Now that some days have passed, I am finally able to look a bit more dispassionately at where we're at. Firstly, let's look at the compiled binary itself. By default, Wastrel passes the -g flag to GCC, which results in bi

## Wastrel Compiles Hoot Scheme-to-WebAssembly Output

DevFeed: [Wastrel Compiles Hoot Scheme-to-WebAssembly Output](<https://devfeed.tech/articles/wastrelly-wabbits-35034.md>)

Original publisher: [Read original article](<https://wingolog.org/archives/2026/03/31/wastrelly-wabbits>)

Author: Andy Wingo

Published: 2026-03-31T20:34:23Z

Content type: article

Language: en

Sources: [wingolog](<https://devfeed.tech/sources/wingolog.md>)

Topics: [WebAssembly](<https://devfeed.tech/topics/web-assembly.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [scheme](<https://devfeed.tech/topics/scheme.md>)

Tags: [accidentally-quadratic](<https://devfeed.tech/tags/accidentally-quadratic.md>), [aot](<https://devfeed.tech/tags/aot.md>), [bigint](<https://devfeed.tech/tags/bigint.md>), [bignums](<https://devfeed.tech/tags/bignums.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [compilers](<https://devfeed.tech/tags/compilers.md>), [exception-handling](<https://devfeed.tech/tags/exception-handling.md>), [exceptions](<https://devfeed.tech/tags/exceptions.md>), [gc](<https://devfeed.tech/tags/gc.md>), [gcc](<https://devfeed.tech/tags/gcc.md>), [gmp](<https://devfeed.tech/tags/gmp.md>), [hoot](<https://devfeed.tech/tags/hoot.md>), [igalia](<https://devfeed.tech/tags/igalia.md>), [library](<https://devfeed.tech/tags/library.md>), [maps](<https://devfeed.tech/tags/maps.md>), [precision](<https://devfeed.tech/tags/precision.md>), [scheme](<https://devfeed.tech/tags/scheme.md>), [standard](<https://devfeed.tech/tags/standard.md>), [tail-calls](<https://devfeed.tech/tags/tail-calls.md>), [wasm](<https://devfeed.tech/tags/wasm.md>), [wastrel](<https://devfeed.tech/tags/wastrel.md>), [webassembly](<https://devfeed.tech/tags/webassembly.md>), [whippet](<https://devfeed.tech/tags/whippet.md>)

### AI overview

The article describes recent work on Wastrel, an ahead-of-time WebAssembly compiler, including compiling output from the Hoot Scheme-to-Wasm compiler. It covers implementing bignum operations with mini-gmp and updating Hoot to use standardized WebAssembly exception handling.

### Source excerpt

Good day! Today (tonight), some notes on the last couple months of Wastrel, my ahead-of-time WebAssembly compiler. Back in the beginning of February, I showed Wastrel running programs that use garbage collection, using an embedded copy of the Whippet collector, specialized to the types present in the Wasm program. But, the two synthetic GC-using programs I tested on were just ported microbenchmarks, and didn't reflect the output of any real toolchain. In this cycle I worked on compiling the output from the Hoot Scheme-to-Wasm compiler. There were some interesting challenges! bignums When I originally wrote the Hoot compiler, it targetted the browser, which already has a bignum implementation in the form of BigInt, which I worked on back in the day. Hoot-generated Wasm files use host bigints via externref (though wrapped in structs to allow for hashing and identity). In Wastrel, then, I implemented the imports that implement bignum operations: addition, multiplication, and so on. I did so using mini-gmp, a stripped-down implementation of the workhorse GNU multi-precision library. At some point if bignums become important, this gives me the option to link to the full GMP instead. Bignums were the first managed data type in Wastrel that wasn't defined as part of the Wasm module itself, instead hiding behind externref, so I had to add a facility to allocate type codes to these "host" data types. More types will come in time: weak maps, ephemerons, and so on. I think bignums would be a great proposal for the Wasm standard, similar to stringref ideally (sniff!), possibly in an attenuated form. exception handling Hoot used to emit a pre-standardization form of exception handling, and hadn't gotten around to updating to the newer version that was standardized last July. I updated Hoot to emit the newer kind of exceptions, as it was easier to implement them in Wastrel that way. Some of the problems Chris Fallin contended with in Wasmtime don't apply in the Wastrel case: sinc

## nominal types in webassembly

DevFeed: [nominal types in webassembly](<https://devfeed.tech/articles/nominal-types-in-webassembly-35032.md>)

Original publisher: [Read original article](<https://wingolog.org/archives/2026/03/10/nominal-types-in-webassembly>)

Author: Andy Wingo

Published: 2026-03-10T08:19:34Z

Content type: article

Language: en

Sources: [wingolog](<https://devfeed.tech/sources/wingolog.md>)

Topics: [WebAssembly](<https://devfeed.tech/topics/web-assembly.md>), [wasm](<https://devfeed.tech/topics/wasm.md>)

Tags: [exceptions](<https://devfeed.tech/tags/exceptions.md>), [hoot](<https://devfeed.tech/tags/hoot.md>), [igalia](<https://devfeed.tech/tags/igalia.md>), [isorecursive-types](<https://devfeed.tech/tags/isorecursive-types.md>), [nominal-types](<https://devfeed.tech/tags/nominal-types.md>), [structural-types](<https://devfeed.tech/tags/structural-types.md>), [type-equality](<https://devfeed.tech/tags/type-equality.md>), [types](<https://devfeed.tech/tags/types.md>), [wasm](<https://devfeed.tech/tags/wasm.md>), [wastrel](<https://devfeed.tech/tags/wastrel.md>), [webassembly](<https://devfeed.tech/tags/webassembly.md>)

### AI overview

This article explains WebAssembly's structural type equality, how recursive type groups approximate nominal typing within a module, and how the nominal typing proposal adds nominal types for stronger separation between types across modules.

### Source excerpt

Before the managed data types extension to WebAssembly was incorporated in the standard, there was a huge debate about type equality. The end result is that if you have two types in a Wasm module that look the same, like this: (type $t (struct i32)) (type $u (struct i32)) Then they are for all intents and purposes equivalent. When a Wasm implementation loads up a module, it has to partition the module's types into equivalence classes. When the Wasm program references a given type by name, as in (struct.get $t 0) which would get the first field of type $t, it maps $t to the equivalence class containing $t and $u. See the spec, for more details. This is a form of structural type equality. Sometimes this is what you want. But not always! Sometimes you want nominal types, in which no type declaration is equivalent to any other. WebAssembly doesn't have that, but it has something close: recursive type groups. In fact, the type declarations above are equivalent to these: (rec (type $t (struct i32))) (rec (type $u (struct i32))) Which is to say, each type is in a group containing just itself. One thing that this allows is self-recursion, as in: (type $succ (struct (ref null $succ))) Here the struct's field is itself a reference to a $succ struct, or null (because it's ref null and not just ref). To allow for mutual recursion between types, you put them in the same rec group, instead of each having its own: (rec (type $t (struct i32)) (type $u (struct i32))) Between $t and $u we don't have mutual recursion though, so why bother? Well rec groups have another role, which is that they are the unit of structural type equivalence. In this case, types $t and $u are not in the same equivalence class, because they are part of the same rec group. Again, see the spec. Within a Wasm module, rec gives you an approximation of nominal typing. But what about between modules? Let's imagine that $t carries important capabilities, and you don't want another module to be able to forge those c