Answers:
用英语将分号用于分隔语句列表中的项目,例如
她看到了三个男人:来自新西兰的杰米(Jamie);送牛奶者的儿子约翰;还有一个,弱的乔治。
进行编程时,您将分隔多个语句,并且使用句号可能会很容易混淆小数点。使用分号提供了一种易于解析的方法,可以在保持接近正常英语标点的同时分离各个程序语句。
编辑以添加
在内存昂贵,处理缓慢以及最初的编程语言正在被设计的早期,有必要将程序拆分为单独的语句进行处理。某些语言要求将每个语句放在一行上,以便回车可以用作语句定界符。其他语言允许文本布局使用更自由的格式,因此需要特定的分隔符。选择该字符作为分号,很可能是因为它与英语中使用的相似(这必须是一个假设;我当时不在那儿),因为它与其他标点符号没有冲突数学或其他语法目的所需的标记和符号。
再次编辑
某些终止符的需求可以追溯到解析语言文本的要求。早期的编译器是用汇编语言编写的,或者在某些情况下是直接用手工制作的二进制机器指令编写的。具有特殊的字符可以标识语句的末尾并分隔正在处理的文本块,这使处理变得容易得多。正如我上面所说的,其他语言也使用回车符或括号。Algol,Pascal,Ada,BCPL,B,C,PL / M和其他语言族碰巧使用分号。至于哪个人是第一个使用这个特殊角色的人,我在历史上回想起来还不够。它的选择和采用非常合理,因为
最后,我想在设计这些答案和评论所用的第一种语言时,花在确定答案上的时间要比决定使用分号结束语句所花费的时间更多。
许多语言都使用模仿C的语法(模仿模仿B的语法-感谢@Crollster)。从评论中可以看出,这类语言有很长的篇幅……B受到PL / I的启发,ALGOL则在前面使用了A ;
作为分隔符。
由于在C中语句终止符为;
,因此这些语言也照搬。
至于为什么选择它作为C中的语句终止符-可能是因为其在英语中使用“表示相互依赖的语句”。
在字符集可用的存储空间有限的时候,PDP-11上也发明了C语言,因此语言的发明者必须在这些限制内工作。
FORTRAN用回车符来描述语句。COBOL使用期限。LISP不使用任何内容,而是使用括号来表示所有内容。ALGOL是第一种使用分号分隔语句的语言。PASCAL遵循ALGOL的领导,使用分号分隔语句。
PL / I使用分号终止语句。有一个区别,在PASCAL中很容易看到。Ada在这一项目上遵循PL / I的领导,而不是ALGOL的领导。
以分号作为语句分隔符或终止符已被计算机科学社区迅速接受为一种有用的表示法,据我所知,随后的每种块结构语言都遵循ALGOL的领导,并使用分号来分隔或终止语句。
多年以前,我曾被告知BCPL使用分号和回车符作为语句分隔符/终止符,但我本人从未使用过该语言,因此无法验证这一点。在某些时候,从BCPL后代中删除了使用回车来分隔或终止语句。BCPL产生B,B产生C,C产生C ++,Java,D以及比PASCAL和Ada少得多的思想。
为什么没有其他符号?
几种语言使用了其他符号-例如,旧版BASIC使用冒号代替。
但是,我忽略了少数例外,主要有两个原因。首先,您只是在寻找明确的内容。在典型的解析器中,如果遇到足够严重的错误以致无法继续解析当前语句,则通常尝试通过直接跳到语句终止符并从重新启动解析器来使解析器恢复同步。下一条语句的开始。为此,您希望某些东西通常不会在代码中的其他任何地方出现,而分号恰好是一个没有附加其他含义的符号,因此很容易将其专用于此目的。
第二个原因有些相似,但更多地针对人们阅读/使用代码。同样,它又回到了一个事实,即您使用的实际符号无关紧要。在可能的情况下,使用读者习惯于特定目的的符号来获得可读性上的实质性优势。这并不意味着C是一种完美的语法,其他所有事物都应该严格遵循它,但这确实意味着有足够的人熟悉这种语法风格,而模糊的相似语言通过遵循它会收获很多(而损失很少)尽可能使用大致相同的语法。
我会注意到,这就像设计几乎任何其他程序一样。如果我编写的程序使用某种形式的Windows,我将尝试仅使用目标平台的本机功能。体现的许多决定在很大程度上都是武断的,并且可以以不同的方式执行而不会造成功能上的重大损失-但是同样地,在不大幅增加功能的情况下更改它们只会使用户感到困惑,而无法完成任何有用的工作。相同的基本原则适用于“应该用什么终止(或分开)某种语言的语句?” 如“滚动条的外观如何”或“树控件应如何工作?” 在所有这些情况下,决策基本上都是任意的,并且统一性本身就提供了很大的好处。
我要补充说,在许多种语言中都发生了同样的事情,只是在编程之前,我们大多数人已经习惯了这种方式,很少有人考虑它。为什么每个人都用“ +”表示加法,或用“-”表示减法?因为符号的形状无关紧要,但是每个人都同意对每个符号应用相同的含义非常重要。
分号最初是在Algol 60中提出的,用作语句分隔符,而不是终止符。
在Algol 60之前,Fortran是唯一存在的高级编程语言,它要求每个语句都在单独的行上。像do循环一样,跨越多行的语句被认为是奇怪的,它们被视为“语句块”。
Algol 60的设计人员意识到,语句需要分层结构(if-then-else,do-loop,case语句等),并且它们可以嵌套在彼此内部。因此,将每个语句放在单独的行上的想法不再有意义。S1形式的语句的顺序组成;S2; ...; Sn可选地包含在开始 - 结束括号中,被称为复合语句,并且适合Algol 60所设想的语句的层次结构。因此,在这里,分号显然是语句分隔符,而不是终止符。
这在实践中引起了问题。Algol 60也有一个“空语句”,它没有写任何内容。因此,可以写出“ 开始 S1;结束 ”,分号看起来好像在终止S1。但是Algol 60编译器确实将其视为S1和其后的不可见空语句之间的分隔符。这些微妙之处对于实际的程序员来说有点多。他们已经习惯了诸如汇编语言和Fortran之类的面向行的语言,他们确实认为分号是语句的终止符。编写程序时,通常将分号放在语句的末尾,如下所示:
a [i]:= 0; 我:=我+1
分号确实看起来像第一个语句的终止符。如果程序员将分号视为终止符,则这样的语句将产生语法错误:
如果我> 0,那么 a [i]:= 0; 其他 a [i]:= 1;
因为分号终止了“ if”,所以“ else”变得悬空了。程序员们被彻底弄糊涂了。
因此,PL / I,即IBM面向行的Fortran的继承者,决定将分号作为语句终止符而不是分隔符。程序员对此选择感到满意。大多数编程语言都紧随其后。(Pascal拒绝了这种趋势,但其继任者Ada放弃了这一趋势。)
[注:维基百科上有关编程语言比较的文章有一个很好的表格,总结了如何在各种编程语言中处理分号。]
这几乎是纯粹的猜测工作,但是查看受限于ASCII值的标准QWERTY键盘,终止/分隔的自然字符将是。!?::;。和回车。!!中的一个:应立即取消获得多个密钥的资格,并且语句终止将是很常见的事情。句号将被取消资格,因为它们很容易与小数点混淆,由于初始计算机的空间有限,这会使它们不必要地复杂化为终止符。如果代码行的长度可能大于屏幕上一行上显示的行数,那么回车符将被取消资格,因此,当必须水平滚动行时,阅读程序会更加困难,或要求其他字符在下一行上创建延续,这又增加了复杂性。离开了; 作为选择中的一种,相比于;之所以选择分号,是因为它更易于键入,不会造成混淆,因为它为有限意义的字符增加了含义,并且也因为复杂的使用情况而真正没有特殊情况,因此使之不太复杂。
选择分号是因为它是基于懒惰和简单性的最佳字符。
这很大程度上是一个任意选择。一些语言做出了其他选择。COBOL以该.
字符终止语句。FORTRAN,BASIC和Python通常以换行符终止语句(对于多行语句使用特殊语法)。Lisp用括号将其声明括在括号中。
;
语句分隔符/终止符之所以如此流行,主要原因是当今大多数流行语言都基于使用该约定的ALGOL。
而不是其他符号?
您还能选择什么其他符号?
ASCII字符#$ @ [] ^ _`{|}〜并不总是出现在ISO 646之类的早期字符编码中。
这些字符()*+-/<=>
通常用作数学运算符,如果用作语句终止符,则会产生歧义。
product = a * b * // If '*' were a statement terminator,
c * d * // Are there two factors, or four?
类似的问题将适用于'
和"
,通常用作字符串定界符。,
,通常用于分隔函数参数,而.
,通常用作小数点(或在类似的结构中用作分隔符some_struct.some_field
)。
离开!%&:;?
。
选择!
或?
可能不会造成技术上的困难,但是它们的英语含义会使程序产生错误的心情。
print(x)? # Yes, you should.
# It's an IMPERATIVE language; stop questioning my commands.
print(x)! # OK! You don't have to shout!
&
作为语句分隔符(而不是终止符),这将是更明智的选择,因为
do_thing_a() &
do_thing_b()
可以理解为一个命令做事情,并随后做的事情B.但是,大多数语言与&
运营商使用它作为一个逻辑或按位AND来代替。
该%
符号可能会导致类似这样的语句混乱interest_rate = 2.99%
(它将变量设置为2.99
而不是预期的0.0299
)。当然,众所周知的数学意义%
并没有阻止C将其用作余数运算符。
使叶片:
和;
。
:
是一个明智的选择,并且确实在大多数BASIC方言中用作行内语句分隔符。
但是;
有英语语法。它可用于分隔句子中的从句。
与其尝试回答您的标题问题,不如将重点放在您的隐式问题上:
我想知道此决策的历史,并希望答案能带来见解,从而可能影响编程语言的设计和实现中的未来决策。
如果您想了解编程语言的设计和实现历史,并且对过程有更多的了解,那么“ 编程语言历史会议”的会议记录将是一个很好的起点。(我认为您将需要ACM成员身份才能访问该程序。)
为什么许多编程语言中的语句都以分号结尾?是否有理由选择分号作为行终止符而不是其他符号?
以您的标题问题为例,您可能希望通过阅读HOPL程序来尝试回答该问题,我想提供以下几点:设计新编程语言的人们之所以这样做,是因为他们认为自己知道的是损坏/不足。一方面,他们的新语言旨在解决这一缺陷。另一方面,语言设计师还将从他们认为不错的其他语言中复制设计元素,或者他们只是不更改自己不会遇到问题的那些元素。
特别是最后一部分很重要:与其试图找出哪一种编程语言是第一个使用分号作为终止符的编程语言,以及为什么很多其他编程语言都复制了这种语言,不如通过查找未复制的语言来学习更多它。例如,虽然Smalltalk从Simula那里获得了很多启发,但它并没有复制其语法,尤其是使用分号作为语句终止符。它将终止符(实际上是分隔符)更改为句号,并将分号用于其他内容。相反,曾经使用分号作为语句终止符的第一种语言可能有理由将其从之前的语言中更改。也有可能是第一种语言引入了语句终止符的整个概念(或独立于其他语言而引入),并且分号由于某种原因而被使用,但现在已经不及时了。(我怀疑后者就是这种情况,因为没有其他答复者能够从介绍分号的人那里找到报价,而不是对为什么分号是个好选择提供了新的假设。)但是,重申一下我的观点。点,我认为您将通过了解语言设计师为何更改事物而不是为什么他们复制/保留它们来学到更多。当人们更改事物时,他们通常希望或不得不解释更改,而当人们复制或保持不变时却不这样做,因为“我们为什么要更改它?这就是完成的方式!”
它的可见性。
早期的语句分隔符为“。”。就像在COBOL和换行符中一样,在FORTRAN中回车。
CR被证明是有局限性的,因为它使得难以在多行上传递语句。
句号停止引起了一个更有趣的问题。当您阅读英文文本时,您的大脑会在下意识的水平上处理句号,您会意识到句子已经结束,可以喘口气,但是您并没有真正注意到。这表明了这一点。同样在许多字体中,“。” 是有时显示为单个像素的最小可能字符。丢失或多余的时间已成为COBOL程序错误的最常见原因。
因此,从早期错误中吸取教训,ALGOL选择了一个特定的终止符,该终止符将使一条语句流经多行,并选择了一个易于阅读且易于阅读的语句。分号既大又普通,足以使普通英语无法下意识地处理。
据我了解,之所以选择它,是因为除了回车/换行之外,还需要一个明确的语句终止符。早在80列的屏幕时代,实际上只有一行代码跨越多行换行很常见,以至于将\ r或\ n用作语句终止符是行不通的。
分号之所以方便,是因为它们不用于逻辑/数学语句中。因此,它们在很大程度上不会与语句的实际内容冲突。
我个人认为,继续使用分号以及将行数保持在80个字符以下的样式要求是坦率的愚蠢和过时的做法。诸如python之类的语言已广泛证明,没有它们,您可以编写易于理解,简洁的代码。另外,如果您遇到的行数超过80个字符的问题,则需要更大的监视器。
我可能是错的,但是我认为这与以下事实有关:在许多汇编器中,分号通常用于在指令后添加注释。后面的所有内容;
均为注释,不再是说明本身的一部分。
然后,当您在解释器中键入指令时,需要终止它们。短指令(例如数学表达式)可以通过简单地按Enter键来终止,告诉解释器表达式已准备好进行计算并产生结果。但是有时人们想要为指令输入多行代码,因此一种实现方法是使用某些特殊字符作为指令的终止符,而不是仅依赖Enter键。这样,用户可以一次输入更多行代码,因为Enter尚未将其发送给解释器。只有当解释器在用Enter输入的行中找到终止字符时,它才最终执行该字符并计算其结果。
现在将这两件事结合在一起,分号似乎是终止符的明显选择:它告诉指令部分在哪里结束,注释部分在哪里开始,因此当解释器在一行中遇到它时,它知道可以刷新缓冲到目前为止表达式的所有行并执行它,因为指令刚刚结束,现在我们在注释中(嗯,至少直到此行的末尾,因为下一行将在代码中开始再次进入模式,开始新的表达式/指令)。
当然,这是假定将分号重新用作指令终止符的人使用的实际上是分号。如果它是其他任何字符,我们可能最终会得到一个不同的指令终止符。
Inb4:不,这不是历史记录。我没有任何证据表明这是分号实现的实际方式。这就是我想象的可能发生的方式。
大多数语言都使用分号,因为它已被广泛用于此目的,并且进行更改毫无意义。
考虑到第一种语言做出选择,您必须考虑哪些替代方法。在设计语言时,您希望所需的字符可用,并且此时的字符集被编码为6位,通常保留一些模式,通常未明确定义某些字符(有关以后的内容,请考虑一下ISO-646的变种国家-美国的变体以及知道名字的ASCII下-这重用代码为“普通”字符,例如[
,#
或者$
,看看在上下文中的效果,其中只有一半多的代码位置可用,字母和数字保留其中的一半以上)。
可能没有其他字符可以直观地用作语句分隔符(.
可能已经是该条件的唯一重要竞争者),并且在解析和词汇化理论仍处于阐述阶段(.
现在是现在)的情况下,没有引入词汇或解析困难。毫无疑问,因为它的实数用法)。