配列の先頭要素が「0番目」であることは気持ち悪いか…「N番目」という言葉を考察してみる

JavascriptやPHPの配列や関数などで 配列の最初の要素がary[0]に… - 人力検索はてな

C言語、RubyLispなど多くの言語では配列は0起点である。つまり、先頭の要素のインデックスは0である。
なぜそうなっているか‥それは実装上の都合であったり歴史的理由だったりする。
C言語の配列は「連続したメモリ空間の、先頭アドレス」で表現している。そして、オフセットを進めることでそれぞれの要素にアクセスしている。だから配列の最初の要素を「0番目」とすることでアドレス計算が楽になるわけだ。
多くの言語はC言語の文法を拝借しているし、C言語は十分普及しているから、「C言語にあわせて配列は0起点でいいや」となっていると推測している。コンピュータの世界じゃ歴史的理由ってのがけっこう多い。
そういうわけでプログラマが配列の要素を数えるとき、勝手に「0番目」→「1番目」→「2番目」と数えている。新しい言語でも0起点とするのは、プログラマにとって自然だ。

しかし、日本語の観点では「0番目」というのはいささか気持ち悪い。「日本語」では、順番に並んでいるものの先頭は「1番目」として数えるからだ。
気持ち悪いのは確かなんだが、こうは考えられないか?「N番目」という言葉は、プログラミングの文脈では「インデックスがN番目」という意味にオーバーライドされていると考えるのだ!言葉なんて文脈によって意味が異なるじゃん。「鯖」という言葉をとってみても、一般的な意味では魚のサバだが、インターネットの文脈ではserverを意味する*1
それでもいささか気持ち悪いのは、(0起点の)「N番目」という言葉は、通常の日本語の意味の(1起点の)「N番目」という言葉で表現できてしまうからだろう。Rubyなどのオブジェクト指向プログラミング言語でいえば「super」だ。

この「N番目」という言葉はかなりの曲者で、プログラミングの解説の文脈でも0起点だったり、1起点だったりするのだ!
たとえば解説でインデックスが「+1」されていれば普通の日本語の「N番目」という意味だ。

ary = [:foo, :bar, :baz]
ary.each_index do |i|
  puts "#{i+1}番目の要素は#{ary[i].inspect}です。"
end
# >> 1番目の要素は:fooです。
# >> 2番目の要素は:barです。
# >> 3番目の要素は:bazです。

一方、Array#[]の解説では「N番目の要素を得る」と書いてある。これは0起点の「N番目」が使われている。Array#[]の解説で「N+1番目の要素を得る」と書かれているのはほとんど見かけない。これは…理解のしやすさ、文章のすっきり度なんだろうね。
こんな感じでプログラミング解説で「N番目」という言葉が出てきたら、プログラマは脳内で無意識に「0起点かな、1起点かな」と考えさせられる。脳味噌のCPUタイムの無駄である(笑)それでも、経験的にプログラミング解説では0起点の「N番目」が使われていることが多いようだ。

どうしても気持ち悪いのが抜けないならば、いっそのこと新しい表現を使えばいいじゃないか。(0から数えて)「N番目の要素」という表現を「インデックスがNの要素」と言い換えてみる。それなら間違いなく0起点なんだからね。

[2008/05/25]追記

ruby - 配列を1番目からはじめてみる - まめめも

class Array
  alias aref_org []
  def [](x)
    aref_org(x - 1)
  end
end

当然、これでは不十分です。 a[1, 2]やa[1..2]の場合に対応できていません。
他にも配列のインデックスを扱うArray#values_atとか、Array#indexとかもありますし。
Array#begin、Array#begin=で起点を指定できればいいのですが…
Rubyオブジェクト指向だから $[ なんて嫌ですw

[2008/05/25]追記

404 Blog Not Found:perl - 配列を1番目からはじめてみる

$[ キターーーーーー(゜∀゜)ーーーーーー!!
Perlな人は「1からやり直しです」を「$[からやり直しです」って言うんだっけか。大昔0か1の代わりに $[ と書いてるのを見てコーヒー吹いたことがある。

[2008/05/25]追記

はてなブックマークコメントより。

これ、現実世界との接点がある説明で結構困る。「HTML上で1番目の<form>を配
列から抽出」と か。0番目の<form>ってあるの? みたいな。結局「HTMLで1番
目の<form>を配列の0要素目から 選択」とか妙な表現に


まったく…そうなんですよorz
やっぱりRubyの配列は起点を指定できると嬉しい…もちろん組み込みで。

[2008/05/25]追記

先頭要素が「1番目」であるFortran - @author pyridoxin

FORTRANCOBOLやBASIC(可変)の配列は1起点ですね。他にはどんな言語があるのでしょう。

しかしなんでCとその子孫達は配列の要素が0からなのだろうか?Fortranは1なのに?だれか教えて?

推測ですが、C言語とFORTRANの問題領域が異なるからでしょう。C言語は機械寄りだからアドレス計算が楽な0起点になっています。
FORTRAN数値計算がメインだから1起点が無難なのでしょう。行列にしたって、左上の要素は1行目1列目の要素(A_1_1)であって0行目0列目の要素とは言わないでしょう。

*1:隠語なんだけどね…。だから正式な文書で使ってはいけないのは言うまでもない。