Memory: Five Strategies, One Choice
Memory management is the defining choice for a language like Mere, and Mere's answer follows straight from its philosophy: don't hide it. Rather than a garbage collector or a single ownership scheme, the programmer picks from a small set of strategies — owned, borrowed, arena, region, stack — and the choice is visible in the type. Why no single strategy wins, and why making the choice explicit is the whole point.
For a language that wants to make the implicit explicit, memory is the first real test. It is the classic hidden cost: where a value lives, who owns it, when it is freed — most languages let you not think about any of it, and pay for that convenience in pauses, leaks, or use-after-free. Mere treats memory as exactly the kind of thing its philosophy says to surface.
The design space
There is no shortage of ways to manage memory, and each is a different answer to “who frees this, and when?”
- Garbage collection — the runtime decides. Easy to write, but allocation and ownership become invisible, and the “when” is not yours to control.
- Manual — you decide, explicitly. Total control, no safety.
- Ownership and borrowing — a single owner, borrowed by reference, freed when the owner leaves scope. Safe and precise, at the cost of ceremony, especially for graph-shaped data with lots of sharing.
- Arenas / regions — allocate many things into one area and free the whole area at once. Excellent for a batch of objects with a shared lifetime — an AST, a request, a frame — and terrible when lifetimes don’t line up.
None of these wins everywhere. Ownership is beautiful for a value with a clear single owner and painful for a mesh of cross-referencing nodes. An arena is perfect for that mesh and useless for a long-lived value that outlives the batch. GC papers over all of it and, in doing so, hides the very thing Mere wants visible.
Mere’s answer: pick, and make the pick explicit
Because no single strategy is right everywhere, Mere does not choose one for you. It offers a small set and asks the programmer to choose per data, with the choice carried in the type. The initial design space was five strategies:
- owned — a single owner; moving it invalidates the old binding (as in Rust). For values with one clear home.
- borrowed — access by reference without taking ownership, in shared or mutable form. For passing data without giving it away.
- arena — allocate into a named arena; everything in it is freed together. Ideal for graph-shaped data, where cross-references inside one arena are free.
- region — a scoped area with a lifetime tied to a block.
- stack — the ordinary, automatic case.
The important part is not the list; it is that the strategy is not silent. A value that lives in an arena says so in its type; a borrowed reference is a different type from the thing it borrows. You do not deduce ownership from context or trust a convention — you read it. That is the same bet as everywhere else in the language, applied to the one resource programs most often get wrong.
The compromise, named
Episode 1 promised that Mere names its trade-offs instead of pretending they don’t exist. Here is this chapter’s, plainly: choosing your memory strategy is more work than letting a GC decide. You have to think about lifetimes; the type system will hold you to it; some patterns that a GC makes trivial become something you design. Mere accepts that cost on purpose, because the thing it buys — being able to read a program and know where its memory goes, with no runtime that quietly decides for you — is exactly what it is optimizing for. And the verbosity that ownership annotations cost is, per episode 1, the cheap resource here.
What comes next
Five strategies is where the design started, not where it landed. Laying them out immediately raised questions that later chapters answer:
- arena and region look suspiciously similar — do we really need both? (The next episode is about collapsing them into one.)
- who is even allowed in an arena? Not everything: a value holding an OS
resource can’t just be freed by resetting a pointer. That constraint —
called
Trivial— and the separate machinery for values that do need cleanup (Drop, run viawith) come a couple of episodes on. - what does “a view into a region” mean precisely? That becomes its own small theory.
So this episode is the map, not the territory. The territory — a unified region model with clear rules about what can live there and how it gets cleaned up — is what the rest of Part II builds. Next: why arena and region became one.