[% setvar title Leave $[ alone. %]

This file is part of the Perl 6 Archive

Note: these documents may be out of date. Do not use as reference!

To see what is currently happening visit http://www.perl6.org/


Leave $[ alone.


  Maintainer: Fred Heutte <phred@sunlight.portland.or.us>
  Date: 29 September 2000
  Mailing List: perl6-language@perl.org
  Number: 355
  Version: 1
  Status: Developing


The array base directive $[ is not just deprecated, it is dissed. But setting $[ = 1 is the mathematically correct method for array addressing and makes it easier for ordinary mortals to do basic tasks with substr(), array addressing and the like. On the other hand, the strong C legacy of starting every integral sequence with 0 is culturally bound and should not be disturbed. Therefore, the correct approach is to make it explicit policy that the status quo will continue.


The first Camel states (p. 68),

  The special variable $[ is the current array base, ordinarily 0,
  as we mentioned.  You can change it to 1 if you prefer the
  FORTRAN approach, and then $#whatever will be equal to @whatever.
  Most Perl programmers prefer to leave $[ at 0.

Those like myself who use Perl extensively alongside database programming find it highly annoying to have two different array bases when dealing with the same data. $[ = 1 provides a nice out for us, since we like to $zipcode = $myaddressline[7] when the Zip Code really is the 7th element, or $lastname = substr($myrecord, 26, 15) for surnames starting at the 26th character of a string.

C programmers find this highly annoying since they are attuned since time immemorial to thinking in binary or vector terms where the count always starts with 0. Given both the machine and cultural realities, it is correct for Perl to have this as the default behavior.

However, $[ always existed for us lesser mortals who prefer the ordinary usage with rindex(), array subscripts and other similar work. This allows us to align our work across the landscape of work contexts from Perl to, say, SQL. (For those who are old-fashioned, from 3GL to 4GL and beyond).

The second Camel takes things much further. $[ is not only deprecated, it is dissed in two separate footnotes on p. 49:

  *For historical reasons, the special variable can be used to
   change the array base.  Its use is not recommended, however.
   In fact, this is the last we'll even mention it.  Just don't
   use it.

  +Unless you've diddled the deprecated $[ variable.  Er, *this*
   is the last time we'll mention it ...

This qualifies as a uniquely dogmatic position in a language and culture otherwise refreshingly free of rigid dogmatism.

For those who prefer the array base to be 0 at all times, the issue may be one of purity, and the value to those of us who like $[ = 1 to be mere convenience. But convenience is a virtue too.

If I want to grab the 16th member of an array, I don't want to have to remember always to subtract one in my head and do something with $myarray[15]. This feels unnatural, which is a clue that perhaps it is. This kind of arithmetic is what machines are good for, and it is an inefficient use of human attention to do so, at least for some of us.

Furthermore, it is mathematically more valid to use an option base of 1 for many common tasks. In Joe Celko's book "Data & Databases: Concepts in Practice" (Morgan Kaufmann, 1999), which I highly recommend in any event, he has this to say (p. 83):

  An ordinal number represents a position (first, second, third, ...)
  in an ordering ...

  This question of position leads to another debate: Is there such a
  thing as the zeroth ordinal number?  Computer people like to have
  a zeroth position because it is handy in implementing data structures
  with relative positioning.  For example, in the C language and many
  versions of BASIC, arrays start with the element zero.  This allows
  the compiler to locate an array element with the displacement formula:

    <base address> + (<element size> * <array index>)

  The idea of a zeroth ordinal number is a mild mathematical heresy.
  To be in the zeroth position in a queue is to have arrived in the
  serving line before the first person in line.

In the end, the correct implementation is the one Perl has always had: make array base 0 the default, for the benefit of programmers and systems with that perspective, but allow a different option base for those who prefer it, partly for convenience and productivity reasons, and partly to retain a state of grace mathematically speaking.


None. We won't even mind snide asides and patronizing glances if you just leave $[ alone.


Something changed in the behaviors related to $[ in 5.6, at least in my usual world (ActiveState). Specifically, $[ is silently overridden in the following case:

  $[ = 1 ;

  @files = (<$ARGV[1]>) ;

Then substr("ABCDE", 3, 1) returns "D". Ouch.

I mentioned this to Gurusamy Sarathy at Usenix in San Diego and he didn't know about it, but it's replicable, and whatever causes this should be fixed or isolated so that the effective meaning of $[ = 1 is preserved in all cases, as it was previously.


Special Variables sections in the Camels.