spritely/hoot
12
69
Fork
You've already forked hoot
10
Hoot is a Scheme to WebAssembly compiler and self-contained WebAssembly toolchain. https://spritely.institute/hoot/
  • Scheme 92.9%
  • WebAssembly 3.8%
  • JavaScript 2.2%
  • M4 0.7%
  • Makefile 0.4%
andywingo 7c255aa8bc
All checks were successful
/ check (push) Successful in 51m26s
/ distcheck (push) Successful in 52m59s
Merge pull request 'Add ability to sort heap type id's so that subtypes are contiguous' ( #820 ) from renumbering into main
Reviewed-on: #820
Reviewed-by: David Thompson <flockofbirbs@noreply.codeberg.org>
2026年01月16日 15:09:52 +01:00
.forgejo/workflows Replace GitLab CI with Codeberg actions. 2025年03月19日 12:46:15 -04:00
bin Fix bin/call.scm 2024年08月12日 17:15:54 +02:00
design Fix compilation of null? 2023年08月25日 16:50:29 +02:00
doc Remove docs for obsolete --emit-names flag and document -g. 2025年11月11日 08:14:01 -05:00
examples Fix REPL stack trimming 2025年03月03日 16:05:51 +01:00
js-runner module: scripts: compile-wasm: Add support for user imports. 2024年10月15日 13:25:10 -04:00
lib Improve min/max to only accept reals, handle NaNs, and normalize exact zeroes. 2025年11月22日 08:14:21 -05:00
m4 Add guile.m4 from Guile, replacing acinclude.m4 2025年11月09日 14:14:27 +01:00
module Add ability to renumber validated wasm 2026年01月16日 13:32:23 +01:00
reflect-js reflect.js: Reorganize instantiation code a bit. 2025年10月21日 14:16:10 -04:00
reflect-wasm Add low-level support for syntax transformers 2024年10月18日 14:50:15 +02:00
test Split validation out to its own module 2026年01月14日 13:34:52 +01:00
.dir-locals.el vm: Refer to types by name, not value 2026年01月14日 13:59:51 +01:00
.gitignore Add terminal REPL example. 2025年01月21日 08:54:19 -05:00
bootstrap.sh Add autotools build system. 2023年06月05日 10:21:15 -04:00
ci-manifest.scm Move manifest.scm to ci-manifest.scm. 2023年07月21日 09:40:28 -04:00
configure.ac Add guile.m4 from Guile, replacing acinclude.m4 2025年11月09日 14:14:27 +01:00
COPYING Add license file 2023年05月04日 10:55:18 -04:00
COPYING.LESSERv3 Improve LGPLv3 handling 2025年11月02日 15:12:41 +01:00
guile Use local Guile wrapper for Geiser. 2025年03月03日 14:48:37 -05:00
guix.scm Add license header to guix.scm. 2025年11月03日 13:53:56 -05:00
hoot.ase Update brightness a bit on logo 2023年02月16日 12:17:27 -05:00
hoot.png Update brightness a bit on logo 2023年02月16日 12:17:27 -05:00
LICENSE.txt Add license file 2023年05月04日 10:55:18 -04:00
Makefile.am Add COPYING.LESSERv3 to EXTRA_DIST. 2025年11月03日 13:47:58 -05:00
pre-inst-env.in Move Scheme standard library out to lib/ 2024年05月06日 13:56:28 +02:00
README.md Improve LGPLv3 handling 2025年11月02日 15:12:41 +01:00
size-metrics.scm ci: Gather binary size metrics. 2024年01月17日 09:17:12 -05:00

Guile Hoot

Hoot logo

Hoot is an ahead-of-time, whole-program compiler for Guile Scheme to WebAssembly (aka Wasm) developed by the Spritely Institute. In addition to the compiler, Hoot contains a full WebAssembly toolchain with an assembler, a disassembler, a linker, an interpreter, etc. Hoot produces binaries that conform to the Wasm 3.0 specification which features tail calls and heap-allocated reference types with garbage collection.

Compatibility

Hoot is compatible with the following Wasm runtimes:

  • Firefox 121+
  • Chrome 119+
  • Safari 26+
  • NodeJS 22+

Hoot is currently unsupported on WASI runtimes.

Compilation and runtime

A whole-program compilation approach has been chosen in order to create smaller binaries at the expense of increased compilation time. As we implement more of Scheme, we hope to preserve this "small programs compile to small files" property, rather than having every compiled program include the whole of Guile's standard library.

Despite whole-program compilation, it's possible for multiple Hoot modules to be bound together and interoperate. Hoot makes a distinction between main and auxilary modules. Main modules include the full Scheme runtime and export their ABI whereas auxilary modules exclude the runtime and import their ABI from a main module.

To run Hoot binaries on web browsers there is an associated JavaScript module that handles booting the Wasm modules with the necessary host imports and translates Scheme values to/from JavaScript. Some non-web targets are hosted by JavaScript implementations (e.g. NodeJS) and those can make use of the same support module.

Project status

Hoot has not yet achieved maximum Guile compatibility, but R7RS-small Scheme is well supported. Despite gaps in compatibility, Guile libraries such as Spritely Goblins are known to compile and run on Hoot.

All Wasm features that Hoot relies upon are available in all major web browsers and NodeJS.

To build and run Hoot, a bleeding-edge Guile built from the main branch in Git is required, as several necessary changes that have been upstreamed to Guile have not made it into a stable release yet.

For a fuller picture of project status, including known limitations, see the "Status" section of our documentation..

But... why the name "Hoot"?

We thought this project deserved a cute project name and mascot, and everyone at the time agreed an owl was nice, and Christine Lemmer-Webber had recently just drawn up this owl pixel art, and so it became the mascot. The name naturally flowed from there.

Installing from a stable release

Note that at the time of writing, Hoot requires a development version of Guile. This may not be the case at your time of reading!

Below are system-specific instructions for installing Hoot.

On Guix

Hoot is already available in Guix:

guix shell --pure guile-next guile-hoot

(The --pure flag is to reduce the likelihood of failure due to system-specific configuration. You may not need this flag.)

On macOS (Homebrew)

Hoot is available in macOS thanks to to Alex Conchillo Flaqué and the Guile Homebrew repository.

Add the Guile Homebrew tap if you haven't already:

brew tap aconchillo/guile

If Guile is already installed with Homebrew, unlink it since we need a newer version:

brew unlink guile

Now, just install Hoot:

brew install guile-hoot

This will also install guile-next, a bleeding edge version of Guile, so it might take a while if there's no bottle available.

Building from source

Easy path: Use Guix

This is by far the easiest path because Guix does all the hard work for you.

First, clone the repository:

git clone https://codeberg.org/spritely/hoot
cd hoot
guix shell
./bootstrap.sh && ./configure && make

If everything went okay then you can now run make check:

make check

Did everything pass? Cool! That means Hoot works on your machine!

Advanced path: Build dependencies on your own

Maybe you want to understand better what Hoot is actually doing, or maybe you want to hack on the version of Guile used for Hoot, or etc! This section is for you.

First, you need to build Guile from the main branch.

Then you can clone and build this repo:

git clone https://codeberg.org/spritely/hoot
cd hoot
./bootstrap.sh && ./configure && make

To run the test suite against a production Wasm host, you will need a V8 distribution such as NodeJS 22+ or a standalone V8 build. NodeJS is recommended.

Building V8 is annoying, to say the least. You need to have depot_tools installed; see https://v8.dev/docs/source-code. Once you have that see https://v8.dev/docs/build to build. You will end up with a d8 binary in out/x64.release (if you are on an x86-64 platform). We discourage this route except in the very unlikely case that you are developing a Hoot feature that requires a fresher V8 than NodeJS provides.

If all that works you should be able to run the test suite:

make check

By default, the test suite runs against both V8 (either NodeJS or V8's d8 tool) and Hoot's Wasm interpreter. If you want to run the test suite with just one or the other, you can use the WASM_HOST environment variable:

make check WASM_HOST=hoot
# OR
make check WASM_HOST=node
# OR
make check WASM_HOST=d8

Try it out

Hoot is a self-contained system, so the easiest way to try it is from the Guile REPL:

./pre-inst-env guile

From the Guile prompt, enter the following to evaluate the program 42 in Hoot's built-in Wasm interpreter:

scheme@(guile-user)> ,use (hoot reflect)
scheme@(guile-user)> (compile-value 42)
5ドル = 42

More interestingly, Scheme procedures that live within the Wasm guest module can be called from Scheme as if they were host procedures:

scheme@(guile-user)> (define hello (compile-value '(lambda (x) (list "hello" x))))
scheme@(guile-user)> hello
6ドル = #<hoot #<procedure>>
scheme@(guile-user)> (hello "world")
7ドル = #<hoot ("hello" "world")>

Hoot also extends Guile's build tool guild with the guild compile-wasm subcommand which can be used to compile and (optionally) run a Scheme file:

echo 42 > 42.scm
./pre-inst-env guild compile-wasm --run 42.scm

The above command compiles 42.scm to Wasm and runs the resulting binary in Hoot's Wasm interpreter. Here's how to run it with NodeJS instead:

./pre-inst-env guild compile-wasm --run=node 42.scm

The binaries can be saved to disk, too, of course:

./pre-inst-env guild compile-wasm -o 42.wasm 42.scm

To actually load 42.wasm you could use the Hoot VM as mentioned above or use a production Wasm implementation such as a web browser. See the manual for further instructions on production deployment and full API documentation.

Examples

For quickly getting started with a new project, see examples/project-template/README.md for an explanation of how to use our project template.

For more examples of using Hoot, check out a some of our other repos:

Contributing

Hoot's Git repository is hosted on Codeberg: https://codeberg.org/spritely/hoot

Bug reports and other issues can be filed here: https://codeberg.org/spritely/hoot/issues

Pull requests are very much welcome!

Licenses

Hoot's source code and documentation is licensed under Apache 2.0 unless otherwise noted in a source file. See COPYING for the full license text and see the license headers in each source file for individual copyright information.

Several files are licensed under the GNU Lesser General Public License version 3 or later, see COPYING.LESSERv3.

The owl mascot graphic (hoot.png, hoot.ase) is (C) 2023 Christine Lemmer-Webber and the Spritely Networked Communities Institute and released under the Creative Commons Attribution 4.0 International license