Darren Duncan wrote:
Larry had some ideas for dealing with the problem, but this is a
matter that should be more widely discussed, particularly among
implementers and such.
A general thought is that a parameter could be marked so that any
argument passed through it is effectively snapshot (which is a no-op
if the type is already immutable, or it is likely lazy/COW if it is
mutable) so further changes to the external version do indeed not
affect our internal copy.
Is the class underlying the type immutable? Could I change the
mutability of the type after the fact? (Really?)
Such as this could solve the problem in the general case.
(However, I should mention in postscript that there may be a
complicating factor which concerns immutable objects which are also
lazy to an extent, eg that may internally cache derived values, such
as their .WHICH, when the derived is first asked for rather than at
construction time, though this doesn't affect their actual value,
which stays immutable. We wouldn't want to lose that ability.)
Um, yes, so thank you all who assist in solving this problem.
Some sugar like "is frozen" on parameters?
Alternatively, "$new = snapshot $old" is interesting since it could be
explicitly optimized for performance.
But your earlier question is a good one. How much can you depend on the
(im)mutability info the compiler has? What about runtime?
On the other hand, how much of this is really needed? In other words, to
what extent are people passing objects that they WANT to be volatile,
versus the extent to which they are passing objects where volatility
would be fatal? Should "is frozen" be the default behavior, with
auto-cow part of the entry code unless overridden? Or is volatility a
more useful norm, so that requiring a statement inside the block is the
right "awareness" for something so weird?
=Austin