The following is intended as a draft of the final draft of RFC 120 "Implicit counter in for statements, possibly $#". It includes summarised alternatives based on discussions in this list. It is not intended that this post should revive these discussions. It is a chance for the contributing parties to confirm that their suggestions have been fairly represented. Look out for RFC 1357: "Refract: A meta RFC language". Anyone who cares to debate the usefulness of a RFC definition language within Perl can meet me in the ICA bar at YAPC::Europe. John McNamara. =head1 TITLE Implicit counter in for statements, possibly $#. =head1 VERSION Maintainer: John McNamara <[EMAIL PROTECTED]> Date: 15 Aug 2000 Version: 3 Mailing List: perl6-language-flow Number: 120 Status: Frozen =head1 ABSTRACT The syntax of the Perl style C<for> statement could be augmented by the introduction of an implicit counter variable. The deprecated variable C<$#> could be used for this purpose due to its mnemonic association with C<$#array>. Other alternatives are also proposed: an explicit counter returned by a function; an explicit counter defined after foreach; an explicit counter defined by a scoping statement. =head1 DESCRIPTION The use of C<for> and C<foreach> statements in conjunction with the range operator, C<..>, are generally seen as good idiomatic Perl: @array = qw(sun moon stars rain); foreach $item (@array) { print $item, "\n"; } as opposed to the "endearing attachment to C" style: for ($i = 0; $i <= $#array; $i++) { print $array[$i], "\n"; } In particular, the foreach statement provides a useful level of abstraction when iterating over an array of objects: foreach $object (@array) { $object->getline; $object->parseline; $object->printline; } However, the abstraction breaks down as soon as there is a need to access the index as well as the variable: for ($i = 0; $i <= $#array; $i++) { # Note $array[$i]->index = $i; $array[$i]->getline; $array[$i]->parseline; $array[$i]->printline; } # Note - same applies to: foreach $i (0..$#array) Here we are dealing with array variables and indexes instead of objects. The addition of an implicit counter variable in C<for> statements would lead to a more elegant syntax. It is proposed the deprecated variable C<$#> should be used for this purpose due to its mnemonic association with C<$#array>. For example: foreach $item (@array) { print $item, " is at index ", $#, "\n"; } =head1 ALTERNATIVE METHODS Following discussion of this proposal on perl6-language-flow the following suggestions were made: =head2 Alternative 1 : Explicit counter returned by a function This was proposed by Mike Pastore who suggested reusing pos() and by Hildo Biersma who suggested using position(): foreach $item (@array) { print $item, " is at index ", pos(@array), "\n"; } # or: foreach $item (@array) { $index = some_counter_function(); print $item, " is at index ", $index, "\n"; } =head2 Alternative 2 : Explicit counter defined after foreach This was proposed by Chris Madsen and Tim Jenness, Jonathan Scott Duff made a similar pythonesque suggestion: foreach $item, $index (@array) { print $item, " is at index ", $index, "\n"; } Glenn Linderman added this could also be used for hashes: foreach $item $key ( %hash ) { print "$item is indexed by $key\n"; } Ariel Scolnicov suggested a variation on this through an extension of the C<each()>: foreach (($item, $index) = each(@array)) { print $item, " is at index ", $index, "\n"; } With this in mind Johan Vromans suggested the use of C<keys()> and C<values()> on arrays. A variation on this is an explicit counter after C<@array>. This was alluded to by Jonathan Scott Duff: foreach $item (@array) $index { print $item, " is at index ", $index, "\n"; } =head2 Alternative 3 : Explicit counter defined by a scoping statement This was proposed by Nathan Torkington. foreach $item (@array) { my $index : static = 0; # initialized each time foreach loop starts print "$item is at index $index\n"; $index++; } # or: foreach $item (@array) { my $index : counter = 0; # initialized to 0 first time # incremented by 1 subsequently print "$item is at index $index\n"; } =head1 IMPLEMENTATION As Ilya says, straightforward. =head1 REFERENCES perlvar Alex Rhomberg proposed an implicit counter variable on clpm: http://x53.deja.com/getdoc.xp?AN=557218804&fmt=text and http://x52.deja.com/threadmsg_ct.xp?AN=580369190.1&fmt=text Craig Berry suggested C<$#>: http://x52.deja.com/threadmsg_ct.xp?AN=580403316.1&fmt=text