Larry Wall larry-at-wall.org |Perl 6| wrote:
We also need to consider the "dimension" of referentiality.  I can see
three levels here.  Given

    @a.mung

the .mung could return

    A) a modified @a (treat @a as mutable)
    B) a new array (treat @a as immutable)
    C) a remapped array whose elements refer back to @a's elements

Currently .rotate is defined as A, but I could easily switch it to B,
so you'd have to write

    @a.=rotate;

Having some operation XX return a new object and using =.XX do it "in place" would be consistent with the way other things are shaping up. But people expect push to work like they are used to, and the exported push, called as a sub not as a method, would be copying.
In void context it could give an error.

   push @a, $x;    # what's the point?

if we had a general way to decorate the sub definition to day "must not use in void context".

As expressed already in the synopses, the function called for @a.=push($x); can be written specially to handle the in-place case, rather than have to assign back after copying like the auto-generated case would. (What exactly "define a self.push operator" means needs to be clarified in S12. Is that not the normal sub syntax?) In other words, defining self.push would be the implementation that Perl 5 push is now.


to rotate in place.  If we did that, then we could conceivably set
things up with more PDLish C semantics so that

    @a .= mung          # A semantics
    @b  = @a.mung       # B semantics
    @b := @a.mung       # C semantics

That third one would be rather inefficient. The returned array would need to be set up as an array of binding proxies, if the original wasn't set up as an array of item containers, just in case it gets bound to something (or used as part of a larger expression) rather than assigned.

I'm looking at this general issue right now (musing over it the last week actually) and although it's nowhere near done yet, you can see Figure 1 at <http://www.dlugosz.com/Perl6/web/container-lvalues.html> and the text that is taking shape around it.



This implies, however, that the copy semantics of = are sufficiently
clever to snapshot all the referenced values of @a before clobbering
@a in the case of either:

    @a .= mung
    @a = @a.mung

But list assignment really ought to be doing that in any case.

Wow. The overarching logic for list assignment would have to compare the containers and the arguments in the capture before doing the list assignment to each container, in order to avoid cloning all the containers on the right first in the general case. It can't just copy values out because they may contain iterators or be lazy or be infinite.

--John

Reply via email to