Matthew Hammer and Hazel

Livelits, making them fast, and games my kids design

Hazel#

Hazel is a live functional programming environment: every edit state has a meaning, so a program has a type and a result even while it is incomplete. Hazel is developed by Cyrus Omar's group at the University of Michigan. I co-authored the first Hazel papers and its founding grants, around 2017, and since this fall I have been working on it again.

What I'm working on#

Livelits are GUIs for Hazel values, written as ordinary Hazel code and living inside the program they edit: a slider for a number, a color picker, a figure you pose by dragging. I'm working on user-defined livelits, ones that a Hazel programmer writes, and on making them fast enough to feel like plain apps: moving a slider should redraw a picture as quickly as it would in a small JavaScript page.

That makes it a performance question, and most of my Hazel work right now is answering it, on two pull requests: hazelgrove/hazel#2635 (livelits with modular editors) and #2597 (the full livelits branch). The performance tracking issue is #2609.

Livelits put a GUI inside a Hazel program. I'm also trying the other way around: Hazel inside a GUI's program, as a library its JavaScript event handlers call. That library is hazeljs (on npm): a page hands Hazel a program and JavaScript values, and gets JavaScript values back. I call a program built this way a Hazlet; the game scripts in Messed Up Dress Up are the first, and run on it.

Hazel reports#

The Hazel reports explain that work for anyone following it, and more of the Hazel work besides (a survey of the UI, an answer to why a branch failed CI, a meeting's agenda). Each report takes one question and answers it, with measurements where there are any.

Every report, newest first, with its picture → (and its source on GitHub)

Games with my kids#

The test bed is a set of small games whose features my kids, M and N, choose as they play. The first is Messed Up Dress Up, a paper doll with every part on a slider, and costumes, places and music to go with it. Each request goes live as soon as it's ready, so the next round of play tests it.

The game is a hybrid: a JavaScript page that redraws in milliseconds, whose game logic is written as game scripts, in Hazel by default (with Fumola beside it as another point of comparison). Its toys are also rebuilt in Hazel, as user-defined livelits on the Livelit Playground, where they first took seconds. Closing that gap is what the reports measure. The games' code is on GitHub.

More on what Dress Up is for, and every version of it kept day by day: its music, with a player, its pictures, and its reports on how fast it plays.

How I work#

I work with Claude, Anthropic's AI model, as a partner for the code, the measurements and the writing. The Hazel Work Dashboard shows what we're working on, as it stands: the current ticket, the queue after it, and the pull requests we track. It, its history and our work notes are public on GitHub, though written for the two of us; the reports are the version for everyone else.

Fumola in Hazel#

Fumola, my current language, with Adapton's primitives for incremental computation built in, also runs inside Hazel documents, as described on its Hazel integration page.

Press#

Week in Hazel, Andrew Blinn's weekly digest of the Hazel project, is written and illustrated by AI from the Hazel repository and its GitHub. These issues cover my work, newest first:

  1. Issue 008: One argument at a time.Oct 23–29, 2026Two of my checks now shared by everyone's CI: incremental evaluation compared against evaluation from scratch (#2700), and a step budget that fails a change doing more evaluator work than it should (#2678); a caret kept in view when the font is measured, only if it was in view already (#2672, landed); a shared module's sum type giving its constructors, unqualified, to the code after it (#2729), with stacked tests that found a type-shadowing bug at the seam (#2749); embedded tiles that edit a module and hand its text back to the host page (embed-editable, beyond #2719's read-only frame); functions returned to JavaScript keeping the values they captured (lib-closures).
  2. Issue 007: Room to work.Oct 16–22, 2026A JavaScript library for Hazel (#2711): Hazel.analyze and Hazel.run, values crossing as JavaScript numbers, arrays and tagged objects, so a lever pull in Messed Up Dress Up travels into a Hazel rule and comes back as commands, with named modules assembled by Hazel (#2719); my ascription-copying repair landed on dev (#2679); counting the term nodes a step builds, not only the steps (#2697: 21,155 nodes against 27,777, both 195,319 steps); the incremental-versus-fresh random property back, with recursive templates (#2700); per-member module analysis carried into the livelits × modular editors integration (#2699: 43 of 43 DefStaticsParity cases); caret placement and drag selection in embedded tiles (embed-selectable).
  3. Issue 006: Keep the steps.Oct 9–15, 2026The Livelit Playground and its Scenes on my livelits × modular editors branch (#2635), with the outline's dev and UX modes; an unchanged forest that stopped re-running once recursive helpers no longer looked free (#2675: 5 bindings re-run, not 25); reuse by Merkle hash (#2673); step budgets in CI (#2678); the font no longer scrolling the editor (#2672); long types shown whole in the cursor inspector (#2676).
  4. Issue 005: Who tests the test?Oct 2–8, 2026The eval worker in Firefox, without false timeouts (#2652); a module definition analyzed once (#2651); Hazel's state and Fumola instances on an Internet Computer canister (#2650); and my probe-pin fix from #2635, carried into the livelits branch by Andrew Blinn (#2640).
  5. Issue 004: The controls are code.Sep 25–Oct 1, 2026User-defined livelits running splice commands and expanding quoted code (#2597); the livelits × modular editors draft (#2635); splices that read and write a Fumola instance (#2616); every colour a stylesheet reads being one the theme defines (#2613).
  6. Issue 003: Mind the gaps.Sep 18–24, 2026Each error reported once, not once per wrapper (#2592); the livelit signature with its Functional and Macro expansions (#2597).
  7. Issue 002: A place to try.Sep 11–17, 2026The Fumola integration telling which pass of Hazel ran a program; a builtin Livelit signature for user-defined livelits (#2576).
  8. Issue 001: The cabinet is open.Sep 4–10, 2026 (pilot)Fumola running inside Hazel documents; the evaluator compiled to WebAssembly, about 3.5× faster on the corrected benchmarks (#2490); a flaky test's real cost, a needless revert (#2482); a Blackboard proof-assistant prototype (#2525).