To see what is currently happening visit http://www.perl6.org/
Optional 2nd argument to pop() and shift()
Maintainer: Jonathan Scott Duff <duff@pobox.com> Date: 7 Aug 2000 Last Modified: 1 Sep 2000 Mailing List: perl6-language@perl.org Number: 56 Version: 3 Status: Developing
The inverse operations to pop() and shift() both accept a LIST to
"add" to an array, yet pop() and shift() only remove one element
from an array. In the interest of symmetry and TMTOWTDI, pop() and
shift should allow the programmer to remove multiple items from an
array.
The intent should be obvious, but I'll point it out anyway.
The documentation for Perl 5.6.0 states that pop has one of two forms:
pop ARRAY, or just pop. This RFC proposes that a third form be
added to pop()
EXPR would be evaluated to determine the number of elements to remove
from the end of ARRAY and that number would be removed and returned.
Thus pop() would be a more natural inverse to push() (If you can
add multiple elements to an array with push(), why can't you remove
multiple elements from an array with pop?)
This functionality can currently be accomplished with splice(), but
it is non-obvious that splice() should be the routine to call and
the method isn't at all intuitive. To "pop" the last $N items off of
the end of an array using splice(), the call looks like this:
splice @array, -$N; # remove the last $N items
contrast to the more natural looking
pop @array, $N; # remove the last $N items
Aaron J Mackey <ajm6q@virginia.edu> asked whether or not this should really be equivalent to:
reverse splice @b, -$N; # As if we'd popped each individually
I think that the following should hold:
@a = pop @b, $n; push @b, @a; # @b now in its original state.
Thus, the 2 argument version of pop() should treat the $N
elements as a group.
The semantics for shift() are similar to pop() except that it
operates on the other end of the array. shift() also suffers from
the inability to shift more than one element from the array. Just
like pop(), the two forms of shift() are a shift ARRAY, and
just plain shift. This RFC proposes that a third form be added:
EXPR would be evaluated to determine the number of elements to remove
from the beginning of ARRAY and that number would be removed and returned.
Thus, shift() would be a more natural inverse to unshift. (If
you can add multiple elements to an array with unshift(), why can't
you remove multiple elements with shift()?)
As with pop() the proposed semantics can be accomplished with
splice() and are just as un-intuitive:
splice @array, 0, $N; # remove the first $N elements
contrast to
shift @array, $N; # remove the first $N elements
Again, as with pop(), shift() should treat the first $N elements
of the @array as a group so that the following holds:
@a = shift @b, $N; # remove the first $N elements unshift @b, @a; # put them back # @b is unchanged
@numbers = 1..10; $ten = pop @numbers; # still works @popped = pop @numbers, 3; # Take away 7, 8, 9 push @numbers, @popped; # Put 'em back @popped = pop @numbers, 0; # Nothing happens @popped = pop @numbers, 9; # And then there were none. @numbers = 1..10; @popped = pop @numbers, 100; # And then there were none but # @popped only has 10 things @numbers = 1..10; $one = shift @numbers; # still works @shifted = shift @numbers, 3; # Take away 2, 3, and 4 unshift @numbers, @shifted; # Put 'em back @shifted = shift @numbers, 0; # Nothing happens @shifted = shift @numbers, 9; # And then there were none. @numbers = 1..10; @shifted = shift @numbers, 100; # And then there were none but # @shifted only has 10 things
I don't know the gory details other than it should be possible.
However, there is one implementation detail that occurs to me:
What should happen when the expression given to pop(), or
shift() evaluates to a negative number? I see three options:
1) Nothing. We can only pop/shift positive amounts 2) Act as if the number were positive (i.e. pop @array, abs(EXPR)) 3) C<pop()> would then act as C<shift()> and C<shift()> would act as C<pop()>
I propose that option #3 be adopted since it seems the most Perlian and so far no one has disagreed. :-)
Gisle Aas <gisle@ActiveState.com> mentioned that the behavior of code such as this:
foo(pop @a, "bar");
would be changed by this proposal and that the perl5 to perl6
converter would need to handle this case. Similar provisions would
need to be made for the proposed 2-argument shift()
Several people have commented on the proposed return values for the
new forms of shift and pop. The author of this RFC continues to
maintain that the following identities should hold:
push(@array, pop(@array, $N)); # @array is unchanged unshift(@array, shift(@array, $N)); # @array is unchanged
The Perl 5.6.0 documentation "pop" in perlfunc "shift" in perlfunc "splice" in perlfunc
Comments on return values www.mail-archive.com www.mail-archive.com
Perl5 -> Perl6 translation issues www.mail-archive.com