Closed not-an-aardvark closed 7 years ago
Ah, sorry yeah the documentation doesn't exist yet so I admit there's a little trial and error you have to go through at the moment.
The gotcha in this case is that cloning from mutable to immutable is an unsafe operation. Safe cloning must always be performed from an immutable source. What you need to do is perform any mutations you care about, then commit (formerly "freeze") the changes. To perform further mutations, create a mutable clone thereof. The methods you want are modify()
(and variants) and commit()
.
Take a look at the jsdoc comments for mutation.ts in frptools/core. The main points are:
true
. When the mutability token is set to false, any associated persistent structures are implicitly frozen as a result.modify()
method, or when creating a new, mutable, empty collection/structure), will have the ownership flag set to true
.commit()
function, which toggles the mutability token to the "frozen" position.modify()
function creates a clone of the top level object representing the data structure, and the operations such as set()
, get()
, etc., look at the mutation context attached to each internal node/object that the overall structure is comprised of, and use that as the basis for figuring out which of those internal structures can be mutated directly, or must be cloned as subordinates of the new mutation context.modify()
against an already-mutable object, a reference count is incremented rather than a clone being created. A subsequent call to commit()
will then decrement the reference count rather than performing a final freeze on the mutation context. This allows a data structure to be mutated freely throughout a call stack without each nested call needing to concern itself with the initial mutability state of the operand. Instead, each can independently call modify()
and commit()
without worrying about inadvertently creating multiple clones of the original object. All that is required is that any call to modify()
should eventually be paired with a call to commit()
, assuming you don't just leave it mutable forever.As I said, take a look at mutation.ts
and let me know if you have any questions.
I see, thanks for clarifying. Closing this issue since it's not a bug.
Using current master (https://github.com/frptools/collectable/commit/84d7bdb4475e823f97405da408514e6fbe6d5d0b):
Expected output:
Actual output:
I encountered this when I tried to use an immutable clone for stable iterators in https://github.com/frptools/collectable/issues/44#issuecomment-314350166. I think I'm using the new API correctly (
freeze
/thaw
seem to have been removed), but let me know if I'm misunderstanding how it's supposed to work.