-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
I posited in issue #3814 that immutability is essential for implementing concurrency safely:
As I explained herein and in the companion thread #1868 there are shared data paradigms which are provably safe at compile-time such as immutable shared data. The Vlang compiler could enforce it by for example only allowing threads to share references to immutable shared data.
Vlang’s type system can enforce immutability, but I don’t see any means to initialize an immutable other than from literals or extant runtime values.
Thus how to initialize some complex immutable objects dynamically; for example initializing an array in a loop before declaring it to be immutable from that point forward? Also we’d like to be able to extract immutables safely from complex mutable code because of the fact that “immutable data structures have a logarithm performance penalty for algorithms that require random access writes.”
We could imagine a constructor function which is allowed to mutate (i.e. initialize) an immutable object. If any pointers (to other object) will be initialized then that constructor function must obey certain rules in order for the immutability invariant to be valid.
Specifically those rules are Pony’s recover
block. Any inputs to the constructor (including any variables in the outer lexical scope if Vlang supports closures?) must not contain any non-sendable pointers; which in Pony’s parlance means they must be capable of conversion (aka being consumed) to an immutable (aka val
).
But Pony’s multifarious reference capabilities model is quite complex, c.f. also. And sending a mutable iso
to another thread seems to violate the “future proofing” via sharing only immutables that I wrote about. So perhaps isn’t desirable to adopt all of Pony’s model? To simplify if you’re only going to support recover
then afaics you’ll only need mutables and immutables. So thus the only sendables would be the immutables.
This proposal wouldn’t eliminate the ability to guarantee that circular references don’t exist in immutables. The recover
blocks mustn’t accept as input any references to soon-to-be, immutable objects who initialization (via another constructor recover
block) has not yet completed. I wrote in #1868:
Note as you may know, immutable data structures have the advantage that they can’t contain circular references, which is important if employing ARC instead of a tracing GC, because ARC can’t collect circular references (although there exist probabilistic designs which attempt to do some localized tracing along with ARC).