Re: RFC 90 (v3) Arrays: Builtins: merge() and demerge()
Christian Soeller wrote: Jeremy Howard wrote: However I like the Numeric Python reshape() semantics better: http://starship.python.net/~da/numtut/array.html Is that in any significant way different from PDL's reshape? http://pdl.sourceforge.net/PDLdocs/Core.html#reshape The Numeric Python version lets you use '-1' for any one dimension, which sets the size of that dimension to make the array fill the new shape as completely as possible.
Re: RFC 90 (v3) Arrays: Builtins: merge() and demerge()
I *still* think it should be "unmerge"! ;-) Damian
Re: RFC 90 (v3) Arrays: Builtins: merge() and demerge()
"DC" == Damian Conway [EMAIL PROTECTED] writes: DC I *still* think it should be "unmerge"! ;-) Hrmpf. It should be reshape. (Which would be its own inverse and saves a keyword.) chaim -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 90 (v3) Arrays: Builtins: merge() and demerge()
Removed perl6-announce x-post Chaim Frenkel wrote: "DC" == Damian Conway [EMAIL PROTECTED] writes: DC I *still* think it should be "unmerge"! ;-) Hrmpf. It should be reshape. (Which would be its own inverse and saves a keyword.) reshape() has already been proposed (RFC 148): http://dev.perl.org/rfc/148.html However I like the Numeric Python reshape() semantics better: http://starship.python.net/~da/numtut/array.html Nate (RFC 148 maintainer) and I are trying to find away of getting the greater flexibility of his proposal with the more intuitive semantics of the Numeric Python version. Hopefully we'll have an RFC or 2 on this shortly. PS: How does one pronounce 'hrmpf'?
Re: RFC 90 (v3) Arrays: Builtins: merge() and demerge()
Jeremy Howard wrote: However I like the Numeric Python reshape() semantics better: http://starship.python.net/~da/numtut/array.html Is that in any significant way different from PDL's reshape? http://pdl.sourceforge.net/PDLdocs/Core.html#reshape PS: How does one pronounce 'hrmpf'? It depends somewhat on your mother tongue ;) Christian
RFC 90 (v3) Arrays: Builtins: merge() and demerge()
This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Arrays: Builtins: merge() and demerge() =head1 VERSION Maintainer: Jeremy Howard [EMAIL PROTECTED] Date: 10 August 2000 Last Modified: 8 September 2000 Mailing List: [EMAIL PROTECTED] Number: 90 Version: 3 Status: Developing =head1 ABSTRACT It is proposed that two new functions, Cmerge, and Cdemerge, be added to Perl. Cmerge(@list1, @list2, ...) would return a list that interleaved its arguments. Cdemerge($num_lists, @list) would reverse this operation. Both functions would return an alias into the original list, not a copy of the elements. =head1 CHANGES =head2 Since v2 =over 4 =item * Described aliasing behaviour of Cmerge and demerge =head2 Since v1 =over 4 =item * Moved list to [EMAIL PROTECTED] =item * Changed name from zip/unzip =item * Pass lists directly in examples, not references =item * Change 2nd argument from $list_size to $num_lists =back =head1 DESCRIPTION It is proposed that Perl implement a function called Cmerge that interleaves the arguments of arrays together, and is evaluated lazily. For instance: @a = (1,3,5); @b = (2,4,6); @merged_list = merge(@a,@b); # (1,2,3,4,5,6) This makes it easy to operate on multiple lists using flexible reduction functions: $sum_xy = sub {reduce ^last+^x*^y, merge($_[0], $_[1])}; print $sum_xy-(@a, @b); # Prints '44', i.e. 1*2+3*4+5*6 In order to reverse this operation we need an Cdemerge function: @merged_list = merge(@a,@b); # (1,2,3,4,5,6) @demerged_list = demerge(2, @merged_list); # ([1,3,5], [2,4,6]) The second argument to Cdemerge is the number of lists that are to be created (i.e. the number of lists that would have been Cmerged for this to reverse the operation). If the list to be demerged is not an exact multiple of the partition size, the final list references are not padded--their length is one less than the list size. For example: @list = (1..7); @demerged_list2 = demerge(3, @list); # ([1,4,7], [2,5], [3,6]) Both Cmerge and demerge do not make a copy of the elements of their arguments; they simply create an alias to them: @a = (1,3,5); @b = (2,4,6); @merged_list = merge(@a,@b); # (1,2,3,4,5,6) $merged_list[1] = 0; @b == (0,4,6); # True =head1 IMPLEMENTATION The Cmerge and Cdemerge functions should be evaluated lazily. Cmerge and Cdemerge return an alias into the original list, not a copy of the elements. Effectively, Cmerge creates an iterator over multiple lists. If used as part of a reduction, the actual interleaved list need never be created. For instance: $sum_xy = sub {reduce ^last+^x*^y, merge($_[0], $_[1])}; $answer = $sum_xy-(@a, @b); should be evaluated as if it read: $answer = 0; $answer += $a[$_] * $b[$_] for (0..$#a-1)); which does not need to create an intermediate list. =head1 REFERENCES RFC 23: Higher order functions RFC 76: Builtin: reduce RFC 91: Builtin: partition
Re: RFC 90 (v3) Arrays: Builtins: merge() and demerge()
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 Cmerge 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.