Most data types in Solidean are shared-immutable:
they are built once and can then be shared freely without risk of races or hidden side effects.
This pattern provides both performance and safety: a foundation for exact, parallel geometry processing.
How it works
-
Initialization phase:
At a low level, a shared-immutable object is first created in an uninitialized state.
AnOperationcan then define its content exactly once.
That content becomes atomically available sometime before the operation finishes (Context::execute). -
No mutation:
Once populated, the object cannot change. You can read from it, share it between threads, and pass it into later operations, but never modify it. -
Lifetime model:
While immutability governs the content, objects still follow a clear lifetime:
they remain valid until explicitly released (or until theirLifetimeexpires, e.g.UntilIndirectRelease).
Which objects are shared-immutable?
TypedBlob: output data, immutable once filled.Surface: user-provided geometry, fixed after creation.Mesh: a set of surfaces plus flags, fixed once constructed.ExactArithmetic: fixed precision and extent; must be recreated for a different bound.
Operations themselves are slightly different: they act like builders.
They allow recording sub-operations, but remain append-only.
Older data is never modified, and operations cannot be reused after execution.
Why immutability improves performance
It is a common intuition that mutability = performance.
In highly parallel systems, the opposite is true:
- No synchronization needed: immutable objects can be shared across many threads without locks.
- No hidden invalidation: nothing changes "behind your back," so caches and references remain valid.
- Zero-copy reuse: since results cannot be mutated, they can safely be referenced in new objects.
A powerful example: meshes
Internally, a Mesh is not a monolithic block but a collection of small shared-immutable surflets.
When you run a Boolean operation:
- Only interacting ("cutting") surflets are newly created.
- All unaffected surflets are simply referenced into the new mesh, zero-copy.
This enables:
- Iterated Booleans: each step only recomputes what changes.
- Branching workflows: you can compute multiple results from the same workpiece without duplicating data.
By contrast, a mutable accumulator or voxel grid approach cannot support this kind of reuse.