What Comes Next: The Edge of the Map
This is a pause, not an ending. The systems are built — a memory model, effects, four backends, a self-hosted compiler, safe concurrency — and what remains is the edge of the map: async through effects, a work-stealing scheduler, the deferred atomics, the self-hosting of the distinctive analyses. None of them is on a schedule. Each is a named condition that would pull it onto the map, because the language grows by demand, not by a wish list.
Seven parts built the systems that make Mere a language: a philosophy and a minimal core, an explicit memory model, an effect system, code generation to four backends held in exact agreement, a compiler written in the language itself and running in a browser, a public existence, and type-safe concurrency. That is a whole thing. It is not, however, a finished thing — a living language is never finished — so this last episode is not an ending but a pause, taken at the current edge of the map, looking at what lies just past it.
The horizon is a list of conditions, not promises
The natural way to close a series like this would be with a roadmap: here is what we will build next. But the discipline the whole series ran on argues against that. Features were never built to a schedule; each was built when a real, present need pointed at it, and deferred — sometimes for a long time, sometimes with a measured receipt — when the need was only guessed. So the honest shape of “what comes next” is not a list of promises but a list of conditions: things on the edge of the map, each with a named trigger that would pull it into the built world. What follows is that list, in that spirit.
Async through effects
The effect system from Part III was built on capability passing, and it leaves a door open: asynchronous execution could be expressed as an effect, handled where the program chooses, in the same vocabulary the language already uses for the rest of its side effects. It is an appealing fit on paper. But the concurrency part already settled the near-term need — the pain point that started it, two loops in one process, is solved by real threads, and I/O concurrency was already handled at the host. So async-via-effects waits on a demand it doesn’t yet have: structured concurrency, cancellation, the shapes that threads-and-channels serve awkwardly. The trigger is a program that genuinely needs those and finds the current primitives too coarse — and when it appears, effects are the natural place to build the answer, because the groundwork was laid three parts ago.
A work-stealing scheduler
Today a spawn is one operating-system thread, which is exactly right for coarse
parallelism — a handful of workers over a par_map — and exactly wrong for very many
small tasks, where the cost of a thread swamps the work it does. The standard answer
is a work-stealing scheduler: a small pool of threads that pass fine-grained tasks
among themselves. It is the largest of the horizon items, a longer road than the
others, and its trigger is specific: a real workload of many small parallel tasks,
rather than the coarse data parallelism the current model already serves well. Until
a program wants that shape, the simpler model is not a placeholder — it is the right
tool for the parallelism people are actually writing.
The deferred, with their receipts
Several things were deferred earlier in the series with their conditions written down, and they sit on the horizon exactly as filed. The atomics and locks from the last episode wait on branch-and-bound or adaptive search becoming a real target, with the API and the example already drafted. The general constraint machinery — qualified types — waits on a program that genuinely needs a polymorphic channel combinator reused across types. The package manager waits on adoption large enough to need one. The self-hosting of the distinctive analyses — the borrow checker, the regions, the effect system, the parts that make Mere itself rather than a generic ML — waits its turn behind the classical core that is self-hosted today. And recognition as a language in its own right, its own syntax highlighting and registration, waits on the use that earns it. Each is a deferred question with a trigger, not an omission.
What doesn’t change
If the features are variables, something stayed constant across all seven parts, and
it is the part most worth carrying forward. The way decisions got made did not vary:
a hard question was narrowed on paper into precise sub-questions, tried in a small
experiment before being committed, and then dogfooded against something real until its
rough edges showed. Where a new problem appeared, the first move was to lean on
machinery already built rather than invent more — the closure representation that made
four backends and then four-way concurrency possible, the Trivial rule that Send
and Sync extended, the with construct that turned out to be the capability
lifecycle, the primitives that par_map desugared into. Restraint was treated as an
act, not a lapse: deciding not to build something meant measuring the cost of its
absence, drafting the answer, and naming the trigger. And the guarantees were held to
honestly in both directions — never claiming soundness that wasn’t there, never
diagnosing a flaw that wasn’t either.
Those are the constants, and they are what a reader can take from this series more durably than any particular feature: not a language to adopt, but a way of building one, where fewer concepts kept distinct beats more concepts quietly merged, and where the thing you can be sure of is worth more than the thing that merely works.
The map has edges, and development will keep redrawing them. When one of the horizon features crosses its named trigger and gets built, it will be a new chapter here, written the same way — narrowed, tried, dogfooded, and told straight. Until then, this is where the language stands: small, explicit, verifiable, and open at the edges. That was always the point.