最近,AndréGarzia发表了一篇不错的博客文章,名为“ Lua,一种被误解的语言”,不幸的是(但不足为奇),HN对此发表了大量评论,涉及的是基于0和1的古老索引问题。您会看到,Lua使用基于1的索引,许多程序员声称这是不自然的,因为“其他语言”都使用基于0的索引。
我将很快撇开事实并非如此-基于1的索引具有悠久的历史,从Fortran,COBOL,Pascal,Ada,Smalltalk等到现在都如此-我将承认绝大多数当今业界流行的语言是从0开始的。因此,让我们避免进行人气竞赛,并提出基于0的索引“本来就更好”,或更糟糕的是“更自然”的说法。
它确实显示了当整个社区发现陈述“给定列表x,x中的第一项是x [1],x中第二项是x [2]”时,其条件是多么不自然。 :)实际上,即使在编程之外,这对于groupthink还是有些令人恐惧的想法!
我想我应该不会对来自HN的groupthink感到惊讶,但是这也令人震惊,一堆HN注释如何给出几乎相同的响应,所有这些都与Dijkstra的同一篇文章相联系,从而捍卫了基于0的索引在本质上更好。向当局隐含上诉。 (好吧,我几年前确实读过Dijkstra的笔记,并没有对此特别信服-顺便说一句,这不是我第一次不同意Dijkstra-但是,如果我们给予它以来自该领域传奇人物的额外权重,然后上面基于1的语言的列表为我提供了更长的不同意见的传说列表-更不用说植根于更悠久历史的标准数学符号了。)
我认为,一个更好的想法不是尝试捍卫基于1的索引,而是尝试回答以下问题:“为什么基于0的索引甚至在编程语言中也是如此?” -当然,当今的首要原因是传统和熟悉其他流行的语言,而且我认为即使是基于0的索引的支持者也同意,尽管事实上大多数人甚至都不会注意到它们没有称之为零号原因。但是,如果某件事的主要原因是传统,那么了解传统是如何开始的就很重要。迪克斯特拉不是。
C被指出是这种风格的普及者。 C的著名历史指出,马丁·理查兹(Martin Richards)是BCPL的前身,该语言旨在简化编写编译器的过程。 C语言的简化方法之一是:将数组索引和指针偏移混在一起。
它告诉人们,每当人们进入非上诉至权威论点来捍卫基于0的索引(包括Dijkstra本人)时,人们如何开始谈论偏移量。那是因为偏移量自然是从0开始的,是相对的量度:这里+ 0 =这里;这里+ 1米=距离这里1米,依此类推。就像数字索引是有序对象的元素的标识符一样,因此使用基于1的序数:卡座中的第一个卡,卡座中的第二个卡,依此类推。
早在1967年,BCPL就做了一个捷径,使p [i](索引)等于p + i的偏移量。 C继承了这一点。如今,所有说索引应基于0的参数实际上都是偏移量基于0的参数,索引是偏移量,因此索引应基于0的参数。这是一个循环的论点。甚至Dijkstra的论点也从差的计算开始,即进行“指针算术”(偏移),而不是建立索引。
如今,人们只是一遍又一遍地重复这些论点,因为“ C胜了”,而现在,1960年代微小的编译器编写捷径出现在Java,C#,Python,Perl,PHP,JavaScript等中,即使这些都不用语言甚至具有指针算法。
有趣的是,如果C没有这样做,而是使用基于1的索引,那么今天的人们肯定会声称C在提供基于1的索引和p [i]以及基于0的指针偏移量方面具有优势。 p +我我可以轻松地想象人们如何认为这是最好的设计,因为在某些情况下,一个场景会比另一个场景产生更自然的表达(类似于同时使用x ++和++ x),而新手如何将它们混在一起显然不是适用于C语言中的底层编程的精妙之处,应该使用带有垃圾回收且不基于0的指针算法的简单语言。