{
  "$type": "site.standard.document",
  "content": "---\ntitle: \"Extempore is alive on aarch64 (part deux)\"\ndescription: \"CI green on four platforms, a migration from TinyScheme to s7, and a 9x\n  compiler speedup from hash table caches and union-find type unification.\"\ntags:\n  - extempore\n---\n\nA quick update on\n[Extempore on aarch64](/blog/2025/12/17/extempore-s-aliiiiive-on-aarch64/):\n\n- [CI is now green](https://github.com/digego/extempore/actions) on macOS,\n  Windows, and _two_ Linux architectures (aarch64 and x64)\n- OpenGL graphics stuff is (soft) deprecated because that's increasingly tricky\n  to maintain and keep up-to-date, but there are\n  [a couple of new WebGPU examples](https://github.com/digego/extempore/tree/aarch64/examples/external);\n  the\n  [shadertoy one](https://github.com/digego/extempore/blob/aarch64/examples/external/shadertoy.xtm)\n  is kind of fun (no full \"xtmrender\" pipeline yet, and no ETA on that\n  unfortunately)\n- along the way I wrote a\n  [tree-sitter grammar](https://github.com/extemporelang/tree-sitter-extempore)\n  for extempore (Scheme + xtlang) and some _very_ hacked-together support for\n  evaling code in [helix](https://helix-editor.com) (which\n  [I'm using these days](/blog/2026/02/18/ben-s-dev-setup-2026-edition/))\n- there's now\n  [a repl](https://github.com/digego/extempore/commit/c76be4d24e3315cc80acb1a244fda6aff7003bce),\n  although only on macOS/Linux at the moment\n- [upgraded to LLVM 22](https://github.com/digego/extempore/commit/1dcdaf94d1)\n  (from 21), which went surprisingly smoothly\n- I'm part-way through updating the docs website (bringing it into the\n  [`docs/` folder in the main extempore repo](https://github.com/digego/extempore/tree/aarch64/docs))\n\n## Compiler guts\n\n**NOTE: these compiler & Scheme changes are in a couple of standalone commits\nand could be reverted in future... experimental stuff. But fun!**\n\nThe biggest under-the-hood change is a\n[refactor of the xtlang compiler](https://github.com/digego/extempore/commit/93dacf79)\nand a migration from TinyScheme to\n[s7 Scheme](https://ccrma.stanford.edu/software/snd/snd/s7.html)---Bill\nSchottstaedt's embeddable Scheme interpreter from CCRMA. s7 was originally\nforked from TinyScheme anyway, so the migration path was relatively\nstraightforward, but it's a much more capable interpreter with proper hash\ntables, first-class environments, and better performance across the board.\n\nOn the compiler side, the old xtlang type checker used assoc-list caches for\neverything---which was fine when type environments were small, but scaled poorly\nfor libraries with heavy generic instantiation. The refactored compiler replaces\nthose with hash table caches, adds union-find for type unification, and moves to\nconstraint-based solving.\n\nHere are ahead-of-time compilation benchmarks for all the core and external\naudio libraries[^bench-setup]:\n\n| Library                             |     Before |     After |   Speedup |\n| ----------------------------------- | ---------: | --------: | --------: |\n| `libs/base/base.xtm`                |      5.59s |     3.24s |      1.7x |\n| `libs/core/math.xtm`                |     16.57s |     4.04s |      4.1x |\n| `libs/core/rational.xtm`            |      6.47s |     3.47s |      1.9x |\n| `libs/core/audiobuffer.xtm`         |      7.45s |     3.49s |      2.1x |\n| `libs/core/audio_dsp.xtm`           |     32.14s |     5.71s |      5.6x |\n| `libs/core/instruments.xtm`         |    109.83s |     8.38s | **13.1x** |\n| `libs/external/fft.xtm`             |      5.71s |     3.99s |      1.4x |\n| `libs/external/sndfile.xtm`         |      9.17s |     3.64s |      2.5x |\n| `libs/external/audio_dsp_ext.xtm`   |      5.51s |     4.28s |      1.3x |\n| `libs/external/instruments_ext.xtm` |     12.57s |     9.26s |      1.4x |\n| `libs/external/portmidi.xtm`        |      4.86s |     3.35s |      1.5x |\n| **Total**                           | **215.9s** | **52.9s** |  **4.1x** |\n\nThe headline number is a 4.1x wall-clock speedup, but each invocation includes\n~3s of startup overhead (there's a hard-coded `sleep` for NSApp initialisation\nbecause reasons). Subtracting that out, the pure compile time went from ~183s to\n~20s---a **9x speedup**.\n\nThe standout is `instruments.xtm` at 13.1x; it's a longer file and works the\ncompiler more than some of the others, which is exactly where the new union-find\nand hash table caches pay off. Libraries showing more modest improvements\n(1.3--1.5x) are dominated by LLVM JIT time and startup overhead rather than\nScheme-level type checking, so there's not much to squeeze out of those on the\ncompiler side.\n\n[^bench-setup]:\n    Benchmarked on Linux x86_64 (AMD Zen 4) with LLVM 22.1.0 and ORC JIT. Each\n    library compiled in a separate `extempore --nobase --batch` process.\n    \"Before\" is commit `44b7b5c5` (TinyScheme, assoc-list caches); \"After\" is\n    commit `93dacf79` (s7 Scheme, hash table caches + union-find + constraint\n    solver).\n\nThis is still all on the\n[aarch64 branch](https://github.com/digego/extempore/tree/aarch64); I'm not\nready to merge to master just yet. If you're an extempore user willing to get\nyour hands a little dirty, try building from source on the tip of that branch\nand running your extempore workloads---I'd appreciate that, including bug\nreports of things that don't work.\n",
  "createdAt": "2026-05-13T23:14:39.742Z",
  "description": "CI green on four platforms, a migration from TinyScheme to s7, and a 9x compiler speedup from hash table caches and union-find type unification.",
  "path": "/blog/2026/02/26/extempore-is-alive-on-aarch64-part-deux",
  "publishedAt": "2026-02-26T00:00:00.000Z",
  "site": "at://did:plc:tevykrhi4kibtsipzci76d76/site.standard.publication/self",
  "tags": [
    "extempore"
  ],
  "textContent": "CI green on four platforms, a migration from TinyScheme to s7, and a 9x compiler speedup from hash table caches and union-find type unification.",
  "title": "Extempore is alive on aarch64 (part deux)"
}