When designing my append-only substrate I came up with a problem: how can one keep all data immutable yet have the concept of mutable data as an extension?
The properties I need are:
- Must keep full history of any “mutable” data.
- The user must not be forced to decide if a piece of data is mutable when producing it initially.
- So-called mutations must not affect the data stored at the original site. (append-only)
The design choice made here can deeply influence any superstructure. So please discuss how such a formal system can work!
My proposals are below.
Proposal 1: Mutable data is a container with a unique identifier
To create a mutable value, write create_mutable(initial_value), which results in mutable_value { identifier: 4242, value: initial_value }.
To update the mutable value, write update_mutable(identifier, new_value).
Proposal 2: Mutation is a special type of reference: an overriding reference
Suppose we already have a value e. It is a plain value, not in a container.
To use it normally, simply apply a function.
To mutate it, write apply(endofunction, overriding e). The value of this expression is equal to apply(endofunction, e), but the reference is annotated with overriding.
To deprecate it (mark as deleted), write apply((_ -> nil), overriding e).
To find the successor to an overridden value, ask the runtime.
Some (at least 3) people saw a lot of hash-like data in my work, and conclude that I use hashes. I would like to correct this understanding.
“Naming by hash” is called content addressing. Content addressing can only be used to address immutable content, not mutable content. This is an a priori truth.
My use of hash-like data is only due to the large, uniform address space. Uniform, because it does not rely on natural language, which is an unexplained power that interferes with the metaphysics of a system. (This was first argued in “UID Everything!”) So, they are still names, just not natural language names.