Is there a reason why the first element of a Zsh array is indexed by 1 instead of 0?

From my experience with modern programming and scripting languages, I believe most programmers are generally accustomed to referring to the first element of an array as index 0 (zero).

I’m sure I’ve heard of languages other than zsh starting array indexing on 1 (one); it’s okay, as it is equally convenient.
However, as the previously released and widely used shell scripting languages ksh and bash both use 0, why would someone choose to alter this common convention?

There does not seem to be any substantial advantages of using 1 as the first index;
then, the only explanation I can think of regarding this somewhat "exclusive feature" to shells would be "they just did this to show off a bit more their cool shell".

I don’t know much of either zsh or its history, though, and there is a high chance my trivial theory about this does not make any sense.

Is there an explanation for this? Or is it just out of personal taste?

Asked By: deekin

||

I think the most plausible answer to this is the reverse array built-in from zsh

If you have an array with 4 elements, lets say myvar=(1 2 3 4) and you want to access the 4th element it will be print $myvar[4], right?

However, if you want to create a loop that will list the elements inside this array backwards, it’s just a matter of using negative indexes:

print $myvar[-1]   # will print 4
print $myvar[-2]   # will print 3
print $myvar[-3]   # will print 2
print $myvar[-4]   # will print 1

This should explain since starting from zero, you will not reach one of those elements as there is no -0.

The second reason behind this is probably the C code related to variables on zsh is using int or double int to define array indexes, and since it uses Two’s Complement to represent negative numbers there is no way to represent -0(Signed zero), like you can do on float point variables.

If you are really used to indexes starting at 0, i suggest you to use the KSH_ARRAYS option to fix this.

And taking the hook of @cuonglm comment, the csh features implemented on zsh are explained here. It seems not to be a historical reason but a way to provide a confortable work environment for those who are used with csh

Answered By: user34720
  • Virtually all shell arrays (Bourne, csh, tcsh, fish, rc, es, yash) start at 1. ksh is the only exception that I know (bash just copied ksh).
  • Most interpreted languages at the time (early 90s): awk, tcl at least, and tools typically used from the shell (cut -f1-3, head -n 3, sort -k1,3, cal 1 2015, comm -1) start at 1. sed, ed, vi number their lines from 1…
  • zsh takes the best of the Bourne shell and csh. The Bourne shell array $@ start at 1. zsh is consistent with its handling of $@ (like in Bourne) or $argv (like in csh). See how confusing it is in ksh where ${@:0:1} does not give you the first positional parameter for instance.
  • A shell is a user tool before being a programming language. It makes sense for most users to have the first element in $a[1]. It also means that the number of elements is the same as the last indice (in zsh like in most other shells except ksh, arrays are not sparse).
  • a[1] for the first element is consistent with a[-1] for the last.

So IMO the question should rather be: Why did David Korn’s choose to make its arrays start at 0?

About your:

"However, as the previously released and widely used shell scripting languages ksh and bash both use 0"

Note that while bash was released a few months before zsh indeed (June 1989 compared to December 1990), array support was added in their respective 2.0 version, but for zsh that was released in 1991, while for bash it was released much later 1996.

The first Unix shell to introduce arrays (unless you want to consider the 1970’s Thompson shell with its $1..$2 positional parameters) was csh in the late 70s whose indexes start at one. And its code was freely available, while ksh was proprietary and often not included by default on Unices (sold separately at a hefty price) until the late 80s. While ksh93 code was released as open source circa 2000, ksh88’s, to this day, never was (though it’s not too difficult to find ksh86a and ksh88d source code on archive.org today if you’re interested in archaeology).

Answered By: Stéphane Chazelas
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.