This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Optional 2nd argument to pop() and shift()

=head1 VERSION

  Maintainer: Jonathan Scott Duff <[EMAIL PROTECTED]>
  Date: 7 Aug 2000
  Version: 1
  Mailing List: [EMAIL PROTECTED]
  Number: 56

=head1 ABSTRACT

The inverse operations to C<pop()> and C<shift()> both accept a LIST to
"add" to an array, yet C<pop()> and C<shift()> only remove B<one> element
from an array.  In the interest of symmetry and TMTOWTDI, C<pop()> and
C<shift> should allow the programmer to remove multiple items from an
array.

=head1 DESCRIPTION

The intent should be obvious, but I'll point it out anyway.

=head2 pop

The documentation for Perl 5.6.0 states that pop has one of two forms:
C<pop ARRAY>, or just C<pop>.  This RFC proposes that a third form be
added to C<pop()>

=over 4

=item pop ARRAY, EXPR

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 C<pop()> would be a more natural inverse to C<push()> (If you can
add multiple elements to an array with C<push()>, why can't you remove
multiple elements from an array with C<pop>?)

=back

This functionality can currently be accomplished with C<splice()>, but
it is non-obvious that C<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 C<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

=head2 shift

The semantics for C<shift()> are similar to C<pop()> except that it
operates on the other end of the array.  C<shift()> also suffers from
the inability to shift more than one element from the array.  Just
like C<pop()>, the two forms of C<shift()> are a C<shift ARRAY>, and
just plain C<shift>.  This RFC proposes that a third form be added:

=over 4

=item shift ARRAY, EXPR

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, C<shift()> would be a more natural inverse to C<unshift>.  (If
you can add multiple elements to an array with C<unshift()>, why can't
you remove multiple elements with C<shift()>?)

=back

As with C<pop()> the proposed semantics can be accomplished with
C<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

=head2 Random examples

        @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

=head1 IMPLEMENTATION

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 C<pop()>, or
C<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. abs(EXPR))
        3) C<pop()> would then act as C<shift()> and C<shift()> would
           act as C<pop()>

The author of this RFC sees arguments for all three.

=head1 REFERENCES

The Perl 5.6.0 documentation
L<perlfunc/pop>
L<perlfunc/shift>
L<perlfunc/splice>

Reply via email to