Notes
2026/09/29

An explicit split between mutable and immutable lists

Here's another spin on mutation in functional languages: Instead of trying to solve in-place mutation implicitly behind the scenes, what if we separate immutable from mutable values, with mutability needing to be declared when a value is created at the top of the stack?

Immutable values then support borrowed references as usual, but they don't support any mutable operations like push / pop / set (and instead raise an error). Immutable values can be turned into mutable values by explicitly copying them (which doesn't have to be a deep copy, a shallow copy would however keep any children immutable).

Mutable values support in-place mutation in O(1) but only support a restricted form of borrowing. There are two options here:

The second option requires scanning the stack but keeps reads infallible and raises errors only on mutation.

A mutable value can always be turned back into an immutable value at no cost.

Either way, the split between mutable and immutable values becomes explicit and copying never happens behind the scenes.