Matthew Wickline wrote:
> (not on list, just tossing this in for discussion)
>
OK--we'll keep you cc'd in on this discussion.
>
> RFC 90 (v3) wrote:
> -> Both C<merge> and <demerge> do not make
> -> a copy of the elements of their arguments;
> -> they simply create an alias to them:
> ->
> 1> @a = (1,3,5);
> 2> @b = (2,4,6);
> 3> @merged_list = merge(@a,@b); # (1,2,3,4,5,6)
> 4> $merged_list[1] = 0;
> 5> @b == (0,4,6); # True
>
<...>
>
> In order for the aliasing thing to work, perl would have to keep
> track of all these aliases through a large number of possible
> operations. Suppose that in the above code, after line 3 I
> decided to to say
> @a = ();
@merged_list == @b;
> Now @merged_list must be seriously adjusted as well. What if I did
> @a = (@merged_list, @b, @a, reverse @merged_list);
> Not only is that likely to be a great deal of work, but I can't
> even begin to think about what the result should be. I don't
> think that it can be defined.
>
On assignment to another list, an array copy would have to occur. In this
case the result of this operation is pretty obvious.
> The problem in that case is that you've got a recursive
> definition with no base case.
>
> So, I would say that an easy solution is to return a non-aliased
> list. If you need the aliasing effect, then you need a way to
> avoid recursion problems (and you probably just have to bite the
> bullet with respect to all the extra bookkeeping work perl would
> have to do).
You're right that there's a lot of bookkeeping, and I'm not sure it's worth
it either. Perl's current slicing operation C<@a[$x1, $x2]> only aliases
when used in an lvalue context:
@a = (4,5,6);
@b = @a[1,2];
@b[0] = 9; # @a == (4,5,6)
@a[1,2] = (8,9); # @a == (4,8,9)
We could do the same for merge(). The downside is that:
@transpose = part(
# Find the size of each column
scalar @list_of_lists,
# Interleave the rows
merge(@list_of_lists);
)
and similar expressions would do an awful lot of copying. Ideally if merge()
didn't alias in an rvalue context, Perl would still optimise away multiple
merge()s, part()s, slices, and so forth so that only one copy occurred.
> I'd want to stuff it in a module, but then I'd want
> to do the same with any other core feature I don't use much, so
> that opinion ain't really worth all that much. ;)
>
This was discussed quite a bit when v1 of this RFC was released. It's a
common operation for working with multidimensional arrays, and for efficient
looping through multiple lists, both of which are important in data
crunching.
If it were in a module, then the elements required to make it's complex
optimization behaviour work would have to be definable in a module. I
haven't seen an RFC that provides such a capability.