なぜナンバリングは0から始めるのか(意訳)

最近Go言語の学習をしています。
Go言語ではsliceによって配列を扱うことが多いのですが、sliceを形成する際には、自動的に半開区間になります。
半開区間になるとは、a[a:b][a,b)、つまりa番目は含みb番目は含まない区間になることを指します。

なぜだろう?と思って調べたところ、Why numbering should start at zero (EWD 831) という記事に出会ったため、それを自己理解用に意訳しました。

区間の表現について

下記の4つの候補から、どれを選択するべきか考えます。

 a)  2 ≤ i < 13
 b)  1 < i ≤ 12
 c)  2 ≤ i ≤ 12
 d)  1 < i < 13

aとbは、左側と右側の差分が部分要素のサイズに一致します。
これが望ましいです。
ではaとbのどちらを選択するべきでしょうか?

bとdのように、下限を除外する場合、最小の自然数から始まるシーケンスを指定する際に非自然数を含める必要があります。
そのため、下限においてはを優先します。

ではその前提で上限を含めると、空の区間を定義する際に区間の右側が不自然になります。

  2 ≤ i < 2  // 空区間
  2 ≤ i ≤ ?? // 空区間の表現が難しい

そのため、上限においては<を優先します

結果、候補の中ではaを優先します。

Remark

シーケンスの添字の開始値に何を割り当てるべきか

区間の表現は上記aで行うという前提のもと、長さNのシーケンスの区間の表現を考えます。
添字を1から始めた場合のシーケンスの区間表現は、

 1 ≤ i < N + 1

になります。 しかし0から始めた場合、

 0 ≤ i < N

になります。こちらのほうが良いです。

そのため、添字の最初には0を採用します。

Remark

↑↑ここまで意訳↑↑

まとめ

  • プログラミングにおいて区間の表現は、下限を含め、上限を含めないようにする
    • [a, b)
  • 配列の添字は0から始める
  • Go言語においても、上記のルールに則っていると思われる