是否有理由选择分号而不是其他符号作为行终止符?
我想知道此决定的历史,并希望答案能导致可能影响未来决策的见解。
#1 楼
在英语中,分号用于分隔语句列表中的项目,例如她看到了三个人:来自新西兰的杰米(Jamie);约翰,送牛奶者的儿子;
编程时,您要分隔多个语句,并且使用句号可能会很容易混淆为小数点。使用分号提供了一种易于解析的方法,可以分离单个程序语句,同时保持接近正常的英语标点符号。
编辑以添加
在内存昂贵,处理速度慢,并且正在设计第一批编程语言,因此需要将程序拆分为单独的语句进行处理。某些语言要求将每个语句放在一行上,以便回车可以用作语句定界符。其他语言允许文本布局使用更自由的格式,因此需要特定的分隔符。选择该字符作为分号,很可能是因为它与英语中的用法相似(这必须是一个假设;我当时不在那儿),因为它与其他标点符号没有冲突数学或其他语法目的所需的标记和符号。
再次编辑
对某些终止符的需求可以追溯到解析语言文本的要求。早期的编译器是用汇编语言编写的,或者在某些情况下是直接用手工制作的二进制机器指令编写的。具有特殊的字符可以标识语句的结尾并分隔正在处理的文本块,这使处理变得容易得多。正如我上面所说的,其他语言也使用回车符或括号。 Algol,Pascal,Ada,BCPL,B,C,PL / M和其他语言族碰巧使用分号。至于哪个人是第一个使用这个特殊角色的人,我在历史上回想起来还不够。它的选择和采用非常合理,因为
它的用法反映了普通英语标点的用法。
其他字符(例如句号)可能已经引起混淆,因为它们已经有一个常见用法(句号也用作小数点)。
可见的标点符号允许自由格式的代码布局。
在派生语言或更高版本的语言中使用类似的分隔符可建立在所有人都熟悉的基础上
最后一点,我认为花在这些答案和注释上的时间要比决定使用分号结束一条语句所花的时间更多设计以这种方式使用它的第一种语言时。
评论
并不完全正确。分号将句子分成多个块:每个块应该是一个工作句子,但是我们使用分号表示两个句子之间有很强的联系。它位于逗号和句号之间的中间位置,因此确实是一个停止点,但它将一个句子链接到下一个句子。上面的句子是:“她看见了三个人;杰米(Jamie):来自新西兰,约翰(John):挤奶者的儿子,乔治(George):个弱的人。”您对分号的使用可以用逗号代替。话题不多,但要旨本质上是相同的;它破坏了语句。
–alex.p
2012年3月13日13:53
@ alex.p实际上会以分号代替逗号,否则会导致句子混乱,这是正确的。
–Ryathal
2012年3月13日14:48
有关分号的重要信息:theoatmeal.com/comics/semicolon
–埃德·詹姆斯(Ed James)
2012年3月13日15:55
@ alex.p:您似乎在说Ian的用法是错误的,但您可能只是在说他对我们如何使用分号的解释是不完整的。如果您说他错了,那您就错了。他对分号的使用完全是常规的,我想比您所举的例子要普遍得多。如果您只是说他没有给出详尽的解释,那么我不确定为什么甚至值得一提。
–iconoclast
2012年3月13日在18:01
@Ian“这必须是一个假设,当时我当时不在那儿”您错过了在(正确)那里使用分号的绝佳机会:)
–特拉维斯·克里斯蒂安(Travis Christian)
2012年3月13日19:38
#2 楼
许多语言都使用模仿C的语法(模仿模仿B的语法-感谢@Crollster)。从评论中可以看到,此类语言的链条很长……B受到PL / I的启发,在此之前是ALGOL使用;
作为分隔符。C语句终止符是
;
,这些语言也是如此。关于为什么选择它作为C语句终止符的原因-可能是因为其在英语中使用“表示相互依赖的语句”。
C也是在PDP-11上发明的,当时字符集可用的存储空间有限,因此语言的发明者必须在这些约束条件下工作。
评论
C只是遵循了其前身“ B”使用分号的约定
– Crollster
2012年3月13日在9:54
B只是遵循其前身“ PL / I”使用分号的惯例:)
–斯科姆斯基
2012年3月13日在12:03
@Skomski-接下来是什么?我正在等待最后一只海龟进来;)
–奥德
2012年3月13日在12:10
-1;伙计们,我们都忘记了极具影响力的ALGOL吗?在您提到的所有其他内容之前,它都有分号作为语句分隔符。 (我不知道这是否是从其他地方获得的)
–hugomg
2012年3月13日12:59
@Oded-我想您会发现它一直都是海龟。 * 8')
– Mark Booth
2012年3月13日14:15
#3 楼
FORTRAN用回车符来描述语句。 COBOL使用期限。 LISP没有使用任何东西,而是依靠括号。 ALGOL是第一种使用分号分隔语句的语言。 PASCAL遵循ALGOL的领导,使用分号分隔语句。PL / I使用分号终止语句。有一个区别,在PASCAL中很容易看到。艾达(Ada)在PL / I的这一主题上,而不是在ALGOL的领导下。
分号作为语句分隔符或终止符已被计算机科学社区迅速接受为有用的表示法,据我所知,
很多年前,我被告知BCPL使用分号和回车符作为语句的分隔符/终止符,但是我从未使用过我自己是该语言,因此无法验证。在某些时候,从BCPL后代中删除了使用回车来分隔或终止语句。 BCPL产生B,B产生C,C产生C ++,Java,D以及比PASCAL和Ada少得多的思想。
评论
应该注意的是,最近重新出现了使用分号或换行符的情况。如果Javascript,Lua,Go和Haskell在语法上有效,则它们都在换行符处包含隐式分号。当然还有一些保留换行符作为分隔符的语言。在这里想到了Shell和Python。
– Jan Hudec
2012年3月13日15:29
+1比“ PASCAL和Ada考虑得少得多”
– Aditya
2012年3月13日18:30
Algol 58(Algol 60的前身)使用分号。请注意,当时,语言的发布形式和实际输入形式之间常常会有所区别,因为输入设备非常有限:仅大写,等等。这种二分法在FORTRAN中并不真正适用,而在FORTRAN中却适用。其他语言数量。
–丹·哈尔伯特(Dan Halbert)
2012年3月13日19:27
@kevincline:您会认为波音777是常用的吗?飞行该飞机的航空电子软件的每一行都是用Ada编写的。
– John R. Strohm
2012年6月25日15:26
@kevincline Skype:用Delphi(帕斯卡)编写。Microsoft尝试在更改它后对其进行了更改,但是由于无法成功移植,因此现在购买了Delphi许可证。在美国看过电视吗?该站可能运行在用Delphi编写的WideOrbit软件上。他们在市场上遥遥领先。曾经去过主题公园吗?票务系统很有可能是用Delphi编写的。帕斯卡遍布各地。只是它提供了如此强大的竞争优势,以至于许多人试图对此保持沉默,以免竞争对手发现。
–梅森·惠勒
16年1月9日,11:24
#4 楼
为什么没有其他符号呢?
几种语言都使用了其他符号-例如,旧版的BASIC使用冒号代替。
忽略一些例外,我认为有两个主要原因。首先,您只是在寻找明确的内容。在典型的解析器中,如果遇到足够严重的错误以致无法继续解析当前语句,则通常尝试通过直接跳到语句终止符并从重新启动解析器来使解析器恢复同步。下一条语句的开始。为此,您希望某些东西通常不会在代码中的其他任何地方出现,而分号恰好是一个没有附加其他含义的符号,因此很容易将其专用于此目的。
第二个原因有些相似,但更多地针对人们阅读/使用代码。同样,它又回到了您使用的实际符号无关紧要的事实。在可能的情况下,使用读者习惯于特定目的的符号来获得可读性上的实质性优势。这并不意味着C是一种完美的语法,其他所有事物都应该严格遵循它,但这确实意味着有足够的人熟悉这种语法样式,而模糊地相似的语言通过遵循它会收获很多(而损失很少)语法大致相同。
我会注意到,这非常类似于设计几乎所有其他程序。如果我编写的程序使用某种形式的Windows,则将尝试仅使用目标平台的本机功能。体现的许多决定在很大程度上都是武断的,并且可以以不同的方式执行而不会造成功能上的任何重大损失-但是同样地,在不大幅增加功能性的情况下更改它们只会使用户感到困惑,而无法完成任何有用的工作。相同的基本原则适用于“应以什么终止(或分开)某种语言的语句?”如“滚动条应是什么样”或“树控件应如何工作?”在所有这些情况下,决策大多数都是武断的,统一性本身就提供了很大的好处。
我要补充说,在许多种语言中都发生了同样的事情,就像我们大多数人一样在编程之前非常习惯,因此很少有人考虑。为什么每个人都用“ +”表示加法,或用“-”表示减法?因为符号的形状无关紧要,但是每个人都同意对每个符号应用相同的含义非常重要。
评论
很好(+1分),尽管我不太同意“大部分是任意的”部分。我认为肯定有一些事情更直观,而另一些则不那么直观。在Windows使用X关闭窗口的过程中,存在一些(也许只是模糊地连接)它已经存在的符号。在OS X对颜色的使用中,肯定会带有强烈的象征意义。 (我暂时忽略了M $ Windows从X Windows窃取X的情况,因为我不记得使用了什么。)
–iconoclast
2012年3月13日18:12
@Brandon:我当然不打算说GUI设计的所有部分都是任意的-也许我应该说“一些”而不是“大多数”。为“关闭窗口”图标定义任何特定形状的不是X,而是取决于单个窗口管理器。
–杰里·科芬(Jerry Coffin)
2012年3月13日18:17
据我所知,原始的Dartmouth BASIC仅使用回车符来终止语句(即每行一个语句)。我认为一行中的多个语句(以冒号分隔)是Microsoft的扩展程序。
– John R. Strohm
2012年3月29日14:32
#5 楼
分号最初是在Algol 60中提出的,用作语句分隔符,而不是终止符。在Algol 60之前,存在的唯一高级编程语言是Fortran,它要求每个语句都放在单独的位置线。跨越多行的语句(如do循环)被认为是奇怪的,被视为“语句块”。
Algol 60的设计师意识到语句需要一种层次结构(if-then-否则,则为do循环,case语句等),它们可以相互嵌套。因此,将每个语句放在单独的行上的想法不再有意义。 S1形式的语句的顺序组成; S2; ...; Sn(可选)包含在开始-结束括号中,称为复合语句,适合Algol 60所设想的语句的层次结构。因此,此处的分号显然是语句分隔符,而不是终止符。
这在实践中引起了问题。 Algol 60也有一个“空语句”,它没有写任何内容。因此,可以写“从S1开始;结束”,分号看起来好像在终止S1。但是Algol 60编译器确实将其视为S1和其后的不可见空语句之间的分隔符。这些微妙之处对于实际的程序员来说有点多。他们已经习惯了诸如Assembly和Fortran之类的面向行的语言,他们确实认为分号是语句的终止符。编写程序时,通常将分号放在语句的末尾,如下所示:
a[i] := 0; i := i+1
分号确实看起来像第一个语句的终止符。如果程序员将分号视为终止符,则这样的语句将产生语法错误:
if i > 0 then a[i] := 0; else a[i] := 1;
,因为分号终止了“ if”,因此“其他”变得悬而未决。程序员彻底困惑了。
因此,PL / I是面向行的Fortran的IBM的继任者,决定使分号成为语句终止符而不是分隔符。程序员对此选择感到满意。大多数编程语言都紧随其后。 (Pascal抵制了这种趋势,但其后继者Ada放弃了。)
[注意:Wikipedia上有关编程语言比较的文章有一个很好的表格,总结了如何用各种编程语言处理分号。]
#6 楼
这几乎是纯粹的猜测工作,但查看受ASCII值限制的标准QWERTY键盘,终止/分隔的自然字符将为。!?::;。和回车。 !!中的一个:应立即取消获得多个密钥的资格,并且语句终止将是很常见的事情。句号将被取消资格,因为它们很容易与小数点混淆,在初始计算机空间有限的情况下,它们将不必要地复杂化为终止符。代码行的长度可能大于屏幕上一行上显示的行数后,回车符将被取消资格,因此,当必须水平滚动行或需要附加字符以换行时,阅读程序将更加困难在下一行创建一个延续,这又增加了复杂性。这离开了;作为选择中的一种,相比于;之所以选择分号是因为它易于键入,不易造成混淆,因为它在有限意义的字符上增加了含义,并且因为特殊情况并不实际使用而减少了复杂性。选择它是因为它是基于懒惰和简单性的最佳角色。
评论
你在这里有一个好点;我只会将“选择”(很难证明)改写为“ ...分号获胜,因为它是基于懒惰和简单性的最佳角色”,
– gna
2012年3月13日15:22
几乎不。以分号作为语句终止符/分隔符的方法始于ALGOL(1958),该方法早于ASCII(工作始于1960年,1963年首次发行,1967年主要发行,1986年最后更新)。
– John R. Strohm
2012年3月13日19:30在
@ JohnR.Strohm对我来说是个新闻,但是对我而言,所有这些都是很古老的历史
–Ryathal
2012年3月13日20:16
这是一个很好的理论,但是现实是,无论如何击键都需要使用Shift键才能到达分号,直到现代键盘输入出现在70年代为止。 (在Wiki文章的底部附近有几张漂亮的照片:en.wikipedia.org/wiki/Keypunch)最有可能只是基于自然的英语规则,这一风潮在同时特别流行。 (我将包括50年代后期的所有语言:ALGOL,FORTRAN,COBOL和SQL,不包括LISP。)ALGOL的分号只是所使用的许多英语约定中的一种,BASIC后来对其进行了进一步扩展。
– SilverbackNet
2012年3月13日22:52
@SilverbackNet,这就是为什么“纯猜测工作”可能不应该成为此处答案的基础。
–user1717828
16年1月9日在16:17
#7 楼
这很大程度上是一个任意选择。一些语言做出了其他选择。 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()
可以被理解为先执行A后执行B的命令。但是大多数语言一个
&
运算符将其用作逻辑或按位与。%
符号可能会在interest_rate = 2.99%
之类的语句中引起混淆(将变量设置为2.99
而不是预期的0.0299
)。当然,%
的著名数学含义并没有阻止C将其用作余数运算符。所以留下
:
和;
。:
是一个明智的选择,确实在大多数BASIC方言中都用作行内语句分隔符。但是
;
具有英语语法方面它可用于分隔句子中的从句。#8 楼
与其尝试回答您的头条问题,不如将重点放在您的隐性问题上:我想了解此决定背后的历史,并希望答案能带来见解这可能会影响编程语言的设计和实现中的未来决策。
如果您想了解编程语言的设计和实现历史,并且对过程有更多的了解,那么可以进行下面的程序编程语言历史大会是一个很好的起点。 (我认为您需要ACM成员身份才能访问该过程。)
为什么许多编程语言中的语句以分号终止?
是否有原因?是选择分号而不是其他符号作为行终止符?
以标题问题为例,您可能希望通过阅读HOPL程序来尝试回答该问题,我想提供以下几点:设计新编程语言的人们之所以这样做,是因为他们认为自己知道的那些语言是不完整的/不足的。一方面,他们的新语言旨在解决这一缺陷。另一方面,语言设计师还将从他们认为不错的其他语言中复制设计元素,或者他们只是不更改自己没有遇到问题的那些元素。
特别是最后一部分很重要:与其试图找出哪种编程语言是第一个使用分号作为终止符的编程语言,以及为什么很多其他编程语言都复制了这种语言,不如通过查找未复制的语言来学习更多它。例如,尽管Smalltalk从Simula中获得了很多启发,但它没有复制其语法,尤其是没有使用分号作为语句终止符。它将终止符(实际上是分隔符)更改为句号,并使用分号代替其他内容。相反,曾经使用分号作为语句终止符的第一种语言可能有理由将其从之前的语言中更改。也有可能是第一种语言引入了语句终止符的整个概念(或独立于其他语言而引入),并且分号由于某种原因而被使用,而现在却因时间而浪费了。 (我怀疑这里是后者,因为没有其他答复者能够从介绍分号的人那里找到报价,而不是对为什么分号是一个不错的选择提出新的假设。)但是,重申一下我的观点。这一点,我认为您将通过了解语言设计师为何更改事物而不是为什么他们复制/保留它们来学到更多。当人们改变事物时,他们通常希望或不得不解释该改变,而当人们复制或保持不变时却不这样做,因为“我们为什么要改变它?那就是完成的方式!”
#9 楼
它的可见性。早期的语句分隔符为'。'。就像在COBOL和换行中一样,FORTRAN中的回车。
CR被证明是有局限性的,因为它使得难以在多行上传递语句。
完全停止引起了更有趣的问题。当您阅读英文文本时,您的大脑会在下意识的水平上处理句号,您会意识到句子已经结束,可以喘口气,但是您并没有真正注意到。这表明了这一点。同样在许多字体中,“。”是有时显示为单个像素的最小可能字符。丢失或多余的期间成为COBOL程序中错误的最常见原因。
因此,从早期错误中学习ALGOL选择了一个特定的终止符,该终止符可以使一条语句流经多行,然后选择是可见的,容易被人类读者注意到。分号既大又普通,足以使普通英语无法下意识地处理。
#10 楼
据我了解,之所以选择它,是因为除了回车/换行之外,还需要一个明确的语句终止符。回到80列屏幕的时代,实际上只有一行代码跨多行换行很常见,以至于使用\ r或\ n作为语句终止符是行不通的。分号只是方便,因为它们不在逻辑/数学语句中使用。因此,它们在很大程度上不会与语句的实际内容发生冲突。
我个人认为继续使用分号以及保留行的样式要求不到80个字符,坦率地说是愚蠢和过时的。诸如python之类的语言已广泛证明,没有它们,您可以编写易于理解,简洁的代码。另外,如果遇到行长超过80个字符的问题,则需要更大的监视器。
评论
早在黑暗时代,就没有“ 80列屏幕”。有80列打孔卡,并且打印机的列数不同。 (大约130左右很常见。)FORTRAN在卡的末尾终止了语句,但允许延续卡继续该语句。延期卡的标记是在卡的第6栏中打出一个字符。 (任何字符都可以使用。根据当地的惯例,通常会看到一个+号或一个数字,多个连续卡的数字向上计数。)
– John R. Strohm
2012年3月13日19:39
像Python这样的语言对于C早期存在的计算机来说是行不通的。使用语句终止符使解析变得更简单,并且减少几十年前编译器的内存和CPU负载非常重要。尤其是在您花了第二秒花费CPU时间的那些计算机上。
–亿加创
2012年3月13日20:35
@Gigatron-我仅指的是使用回车符结束语句,而不是指python的任何更高方面。
–假名
2012年3月13日在21:12
@Gigatron,您可能想看看LISP,尤其是IBM 704上的LISP的早期历史。您可能会对Ancients可以做什么感到惊讶,即使使用石刀和熊皮也可以。
– John R. Strohm
2012年3月13日在21:48
@Gigatron:FORTRAN在同一台计算机上运行,并且使用换行符分隔语句(对多行语句使用特殊语法)。
– dan04
2012年3月14日13:30
#11 楼
这里有两个问题:为什么ALGOL使用分号,以及为什么其他语言采用了分号。第一个问题已经在这里以多种方式得到解答。
作为第二篇,ALGOL被广泛用作算法编写的伪代码语言。因此,分号很快就成为不同语言用户的常识。而且自然而然地,他们被选为年轻的语言。
#12 楼
我可能是错的,但是我认为这与以下事实有关:在许多汇编程序中,分号通常用于在指令后添加注释。;
之后的所有内容都是注释,不再是指令本身的一部分。那么,当您在解释器中键入指令时,需要终止它们。只需按下Enter键即可终止简短的指令(例如数学表达式),告诉解释器表达式已准备好进行计算并产生结果。但有时人们想为指令输入多行代码,因此一种实现方法是使用某些特殊字符作为指令的终止符,而不是仅依赖Enter键。这样,用户可以一次输入更多行代码,因为Enter尚未将其发送给解释器。只有当解释器在用Enter输入的行中找到终止字符时,它才最终执行该字符并计算其结果。
现在将这两件事结合在一起,分号似乎是一个明显的选择终止字符:它告诉指令部分在哪里结束,注释部分在哪里开始,因此当解释器在一行中遇到它时,它知道它可以刷新到目前为止缓冲的表达式的所有行并执行它,因为指令刚刚结束,现在我们要进行注释(嗯,至少要到此行的末尾,因为下一行将再次以代码模式开始,从而开始新的表达式/指令)。
当然,这是假定将分号重新用作指令终止符的人使用的实际上是分号。有了其他字符,我们可能最终会得到一个不同的指令终止符。
Inb4:不,这不是历史记录。我没有任何证据表明这是分号实现的实际方式。这就是我想象的可能发生的方式。
#13 楼
大多数语言都使用分号,因为它已被广泛用于此目的,并且进行更改没有任何意义。考虑第一种选择该语言的语言,您必须考虑什么是分号。备择方案。在设计语言时,您希望所需的字符可用,并且此时的字符集被编码为6位,通常保留一些模式,经常未明确定义某些字符(有关此问题的以后发生,请考虑一下ISO-646的国家变体(美国的变体以ASCII名称广为人知),它重用了诸如
[
,#
或$
之类的“常见”字符的代码,并在只有一半的许多代码位置可用,字母和数字保留其中一半以上。可能没有其他字符可以直观地用作语句分隔符(
.
可能已经是唯一的竞争者)标准),并且在解析和词汇化理论仍处于阐述阶段时,不会引入词汇或解析困难(由于其在实数中的使用,.
现在已成问题)。#14 楼
使用分号的另一个原因是因为它是我们不需要或更经常使用的字符之一。假设我们更经常地将它用作变量名或某些东西,如果分号会被使用如果将其用作关键字或运算符,对于编译器来说将是符号冲突,因此使用在编码中不经常使用的符号非常重要。
我相信C风格的编程语言很受欢迎,因此,新的编程语言的作者不想重新发明轮子,直到现在,他们仍在继续使用它。
评论
Erlang和Prolog使用句号。我想知道您知道多少种编程语言。有许多不使用分号的语言。
我敢打赌,答案会变成类似“分号的ASCII值在用作80个字符的打孔卡上的最后一个字符时特别耐用。”
您的问题还远远不够。真正的问题是,“为什么根本没有任何符号?”
因为它在qwerty键盘的主行上?