이 글은 에츠허르 다익스트라의 서한인 Why numbering should start at zero의 한국어 번역문이며, C++ 반복자는 왜 그렇게 헷갈리는 걸까?의 내용을 보충할 목적으로 작성했습니다. 오역이 있을 경우 댓글로 알려주세요.
번호 붙이기를 0부터 시작해야 하는 이유
자연수의 부분수열 2, 3, ..., 12를 끔찍한 줄임표 없이 나타낼 때, 다음과 같은 4종류의 방식을 고를 수 있다.
- a) \(2 \le i < 13\)
- b) \(1 < i \le 12\)
- c) \(2 \le i \le 12\)
- d) \(1 < i < 13\)
이 중 특정한 방식을 다른 것보다 선호할 이유가 있는가? 그렇다. 방식 a)와 b)는 표기된 상·하한의 차가 부분수열의 길이와 같은 이점이 있다는 관찰은 타당하다. 또한 결과적으로 이들 방식 하에서 두 부분수열이 인접하면 한쪽의 상한이 다른 한쪽의 하한과 같아진다는 관찰 역시 타당하다.1 그러나 이러한 관찰이 타당한 것과 별개로 a)와 b) 중 더 나은 것을 고를 수는 없으니, 원점으로 돌아가 보자.
자연수에는 최솟값이 존재한다. b)와 d)와 같이 하한을 제외할 경우 가장 작은 자연수부터 시작하는 부분수열의 하한이 비자연수가 되어야 한다.2 이는 더러우니 하한은 a)와 c)처럼 ≤로 표기하는 것을 선호한다. 한편 가장 작은 자연수부터 시작하는 부분수열을 생각하자. 상한을 포함할 경우 부분수열이 빈 수열이 되었을 때 상한이 비자연수가 되어야 한다.3 이는 더러우니 상한은 a)와 d)처럼 <로 표기하는 것을 선호한다. 이로써 방식 a)를 가장 우선하는 것으로 결론지을 수 있다.
참고 Xerox PARC에서 개발한 프로그래밍 언어 Mesa에는 네 종류의 방식 전부를 이용해 구간을 표현하는 특수 문법이 있다. Mesa를 이용한 광범위한 실험에서 나머지 세 방식이 꾸준히 어색한 코드와 실수의 원인이 되어 왔음이 밝혀졌으며, 이 실험으로 인해 현재 Mesa 프로그래밍을 할 때는 나머지 세 문법을 사용하지 않는 것이 권장되고 있다. 도움이 될지 모르겠지만, 내가 이 실험적 증거를 언급하는 이유는 현장에서 검증되지 않은 결론을 불편해하는 사람들이 있기 때문이다. (참고 끝.)
길이가 \(N\)인 수열의 원소를 첨자로 구분하려고 할 때, 그 다음으로 난감한 문제는 첫 원소에 무슨 첨자 값을 대응시킬지에 대해서이다. 방식 a)를 따를 때, 첨자가 1부터 시작하면 첨자의 범위가 \(1 \le i < N+1\)이 되지만 0부터 시작하면 더욱 보기 좋은 범위인 \(0 \le i < N\)이 된다. 그러니 서수는 0부터 시작하는 것으로 하자. 그러면 어떤 원소의 서수(첨자)가 그 수열에서 더 앞에 있는 원소의 개수와 같아진다. 또 이 이야기의 교훈은, (그 몇백 년[간의 논쟁?] 끝에!) 0을 가장 자연스러운 자연수로 취급하는 것이 낫다는 것이다.
참고 여러 프로그래밍 언어가 이러한 세부사항에 주목하지 않고 설계되었다. FORTRAN에서는 첨자가 항상 1부터 시작하고, ALGOL 60과 PASCAL에서는 방식 c)를 채택했으며, 더 최근의 SASL은 FORTRAN 방식으로 회귀했다. SASL의 수열은 동시에 양의 정수의 함수이기도 하다. 유감! (참고 끝.)
위의 이야기를 하자니 최근에 우리 대학의 수학과 동료 중 한 명(컴퓨터과학자 아님)가 몇몇 젊은 컴퓨터과학자들을 (습관적으로) 수를 0부터 센다는 이유로 "꼰대"라고 하던 일이 생각난다. 가장 합리적인 방식을 의식적으로 받아들이는 것을 화낼 이유로 받아들인 것이다. ("○○ 끝."을 쓰는 습관도 도발적으로 받아들여지지만, 이 습관은 유용하다. 한 학생이 문항이 첫 페이지의 맨 마지막까지만 있는 줄 알아서 시험에서 거의 낙제했다는 이야기를 들은 적이 있다.) Antony Jay의 이 말이 참 옳다고 느껴진다. "다른 것들과 같이 공동 신앙에서도, 이단자를 추방해야 할 이유는 그가 틀렸을 가능성이 아니라 맞았을 가능성 때문이다."