I'm trying to think how to put this better. In effect, Scalar isn't so much a mutable container object, as it is a bit of magic that changes the fundamental identity of the thing "containing" it, from immutable to mutable. It's sufficiently magic that, barring .VAR, the only way to make one is to delve into the NQP layer which lets you poke and prod (and bend, fold, spindle, and mutilate) the guts of anything. (But rather than actually rewriting the thing containing it, rakudo's implementation requires that all code dealing with values call nqp::decont. I can see why it was done that way --- it's much cleaner than actually mutating its parent --- but you can break stuff by forgetting to decont, and it's not a very scalable way to deal with it. And it means you can defeat the decont and pass mutable things where only immutable ones should exist.)
A proper mutable container should have its own identity but expose the value it contains without an explicit dereference. Scalar goes out of its way to not expose its own identity, which is why the only way to get one is .VAR --- and rakudo depends on this. On Tue, Aug 16, 2016 at 6:07 PM, Zefram <zef...@fysh.org> wrote: > Brandon Allbery via RT wrote: > >I did not mean "You created something equivalent to a mutable-key Pair". > >You *precisely* created a Pair that has a mutable component, in something > >that is not intended to be mutable. > > That view doesn't work for the situation in [perl #128948]. > > It's quite intentional there that it's possible to create a Pair with > a Scalar container in its value slot: I didn't use .VAR. By the view > you're expressing, the situation there is precisely that the Pair is > mutable in respect of its value. The .WHICH that is presently generated > for that situation, of the "Pair|47804193992464" form, follows that view, > attributing the mutability to the Pair itself. > > But I was able to create two Pairs referencing the same Scalar value > container. It's visible that they reference the same mutable storage; > the behaviour upon mutation is different from what would be seen if > each Pair had its own mutable storage. In that ticket the result > was that I had two behaviourally-identical Pairs claiming different > identity. We could paper over that by making the .WHICH value take the > mutable storage identity from the (internal) Scalar, still returning a > "Pair|47804193992464" kind of value, and pretend that the Pairs were > actually the same object. But one can just as well create two Pairs > *with different keys* referencing the same value Scalar, in which case > it's behaviourally visible that the two Pairs are different objects *and* > that they share the value storage. > > So it is untenable to hold that it is the Pair itself that is mutable. > The independent identity of a Scalar container is behaviourally > detectable, even if the object is not directly visible to the language. > > > Scalar is > >precisely the difference between immutable and mutable values. > > The rebinding that occurs in Pair.freeze (which I discussed in [perl > #128955]) shows that the Pair class actually has some mutability of its > own, independent of binding to a Scalar. So Scalar is certainly not > the only way the language implements scalar mutability. There's some > other form of difference between immutable and mutable. > > > It is the implementation of a > >mutable value that can be used as a value; they are *not* general mutable > >containers > > I'm having difficulty discerning what distinction you're making here. > As best I can tell, your view is that the "implementation of a mutable > value" is an inherently second-class concept. That would make it pretty > much by definition a bad idea to reify it. This reasoning doesn't shed > any light on the question of whether the language's main scalar containers > should be reified. > > -zefram > -- brandon s allbery kf8nh sine nomine associates allber...@gmail.com ballb...@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net