这篇文章实在很有意思, 我本来打算翻译出来
http://foorious.com/articles/brief-history-of-programming-languages/
然而篇幅太长我靠机翻才来得及弄完, 所以尽量还是看英文原文吧
一个朋友和我吃午饭的时候问了一个我本来应该能回答的问题
可我只了解一部分: 现代编程语言的历史怎样? 一路上怎么发展过来的?
我跟他说了机器语言, 人们是怎么把它变得更简单
甚至更加激进地设计出更为抽象的语言, 但依然翻译到 0 和 1 运行
然而, 有次偶然我看到 Crockford on JavaScript 这个视频
他讲了整个故事 -- 尽管是围绕 JavaScript 及其影响到的语言
整个故事更加有意思
打孔卡片
一切从打开卡片说起, 就是一些上边有空的纸片(下边有图)
发明
美国宪法要求政府每隔十年进行一次市民的人口普查
到了 19 世纪末, 人口增长如此之快, [1880 年人口普查]用纸笔花了 8 年完成
1890 年, Herman Hollerith 从这项工作当中获得了一个解决方案
最终使用的是打孔卡片存储数据, 通过制表机器来计数和排序
数据被编码在一张严格的纸上的具体的位置, 按照行和列来布局
这样就可以通过机械来处理
Hollerith 的打孔卡片
这次人口普查在一年里完成了
IBM
1896 年, Hollerith 开始了他自己的生意, 成立了
Tabulating Machine Company(制表机器公司)
这个公司向外租赁它的机器, 销售了大量卡片给保险公司和各个国家
具体看 ( http://en.wikipedia.org/wiki/Herman_Hollerith#Inventions_and_businesses )
这个公司后来兼并了其他的公司, 到 1924 年最终成为了
International Business Machines Corporation
是的, 这也就是 IBM.
现代使用
打孔机器被认为是一种很好的把数据输入到机器的方法
IBM 还在用相同的系统, 叫做 Unit Record Management
追溯到 70 年代, 当然相比 Hollerith 最初的方案是要更加自动化了
80 字符限制
实际上, 80 列 12 行. 你应该见过 80 字符限制, 是的, 就是这里来的
因为 80 个字符是一张卡片字符数量最大的宽度
卡片已经淘汰了几十年了, 然而今天我们还有 80 字符限制
图片是 80 列的打孔卡片, 是 20 世纪最广泛使用的款式
卡片当时被用在各种方面. 有时候他们还被当做同伙发给客户
客户仔细处理卡片, 再把卡片和付款一起发回来
然后这个公司会继续操作他们用来注册事务
会计机器是可编程的, 大概是通用现代计算机第一个例子
大型主机/分时 时代
IBM 704 大型主机(照片: Lawrence Livermore 国家实验室)
大型主机是体积巨大(通常都是)用于政府和公司运行关键任务
PS 出现之前(50 年代到 70 年代), 大型主机是人们唯一可以用的计算机
大型主机很昂贵, 只有大型公司和一些大学拥有自己的一台
几乎每一台机器都是独特的, 而且和其他的大型主机完全不同
整个系统由多个单元组成, 会占用整个房间的空间
大型主机把程序和数据都存在存储设备商
要做一个程序, 你需要用极为原始的指令
打孔卡片(再次)
下面是我们从打孔卡片开始讲的原因 :-)
开始执行程序的时候, 你会拿到一堆有你的指令的打孔卡片
作为程序员, 你没有自己的计算机, 而是要在打孔卡片上写程序
(或者纸上, 你可以让别人把它转道打孔卡片上)
然后把它们交给操作员, 他们把卡片输入到你大学或公司的机器上
几个小时以后你再回来, 操作员把结果打印出来, 交到你手里
如果你丢了一个逗号, 你就要修掉错误然后明天再来试一次
还好世界是这样的时候, 我还没生出来. 可以想见程序员日子多惨
分时
由于计算机时间那么昂贵, 所以那段时期, 你最常用的办法是分时
意味着人们共享一台机器, 通过终端连接到大型主机
你会用到只带和电传打字机来写程序, 等到完成再提交程序
电传打字机很慢, 每秒打印 10 个字符, 以为要让程序返回给你尽量简洁
你只在提交工作的时候需要连接电源, 所以编程可以是离线的
(也就是不用一直连接在大型主机上)
分时在 60 年代被引进, 直到 70 年代末都是最常用的编程办法
电传打字机以及打孔的磁带读取器和打孔器, 可以作为电脑终端使用
图片来自 Arnold Reinhold
ASCII
字符集来说, 它们只有极为受限的字符数量, 没有音标字母
所以它只适合用在英文
其中最通用的是 ASCII. 在国家质检分享信息很难, 更不用说亚洲国家
为什么我们称错误为 “bug”?
1889 年,托马斯·爱迪生花了两个晚上修他的留声机,这理应是不能工作的的却发出了声音类似蟋蟀或者说飞虫(Bug)。这导致一个一个笑话, 疯狂的发明家如果数遍了他的发明当中所有的飞虫就能够变得富裕,它是第一个使用记录在案的 “bug” 表示缺陷的使用.
二战期间,Grace Hopper 发现飞蛾砸中了中继器,同时一个计算器停止工作,她把它贴到了笔记当中写道"第一个实际的 bug 被发现了"
第一只计算机 bug 的照片
“mother of all demos”
1968 年, Doug Engelbart 演示了:
鼠标
超文本
屏幕显示器
groupware
视频会议
todo list
他的想法并没有使他富有或者马上流行起来,不过也成了 Xerox PARC 做研究的技术,这给了我们,后来通过苹果 Lisa,Macintosh,最终微软推广的第一个图形用户界面。
视频 The Mother of All Demos, presented by Douglas Engelbart (1968)https://youtu.be/yJDv-zdhzMY
迷你/微型电脑
大型主机之后, 迷你计算机开始出现
最后, 微型计算机成为主流. 微型计算机是智能终端和个人电脑
(尽管当时几乎没人能够独自拥有一台)
微软
每个人都可能知道这个,我不知道,但微软开始于 Altai 8800 -- 一款 DIY 电脑包 -- 运行于一门编程语言,使其在阿尔伯克基的公司 MITS 有点用处。 “微软”,其实就是“微型计算机软件”。
编程语言简史/概述
好了,基本上处于早期的程序员并没有很容易的。
电脑有不同的工作方式,但几乎所有的计算机只懂二进制代码。也就是说,一系列的 0 和 1 的。计算机使用这种方法,因为它与电子开关有着很好的相关性:关=0,开=1,计算机实际上是低级的。
在开始的时候,以计算机编程,你必须说它的语言。也就是说,你需要用 0 和1 一起工作。因为对大多数人来说这显然是一场恶梦,所以计算机科学家们努力尝试抽象这个过程,使人们更容易编写程序。
这里有一个简短的历史和他们的尝试的概述。
机器代码
机器代码或机器语言是一组直接执行该计算机的 CPU 的指令。
每个指令执行一个非常具体和低级的任务。每个由 CPU 直接执行的程序是由一系列这样的指令组成。
数字的机器代码(即不汇编代码)可被认为是编译过的 and/or 组装的计算机程序的最低级表示, 或作为主要和依赖于硬件的编程语言。
虽然可以直接在数字机器代码编写程序,它是繁琐和容易出错来管理各个位和手动计算数字地址和常数。因此,现在很少有这样做,除了那些需要极端的优化和调试的情况。
查阅 http://en.wikipedia.org/wiki/Machine_code#Machine_code_instructions
汇编语言
汇编语言是不是机器代码,但几乎。它直接与底层架构关联,所以没有抽象。
转汇编语言成机器代码,可以使用汇编器。汇编器是第一个发明的软件工具。
下面是一个代码片段:
MOV AL, 1h ; Load AL with immediate value 1
MOV CL, 2h ; Load CL with immediate value 2
MOV DL, 3h ; Load DL with immediate value 3
汇编器是在 50 年代开始使用,因为它们不需要太多的代码分析:大部分的时间,他们干脆把指令并直接转化成其相应的可执行程序的值。作为一个程序员,你要像是底层机器或架构那样思考。
汇编语言上依然在资源有限的电子设备上使用,运行在高级语言和库得到加载之前(例如,硬件固件)。
在 70 年代和 80 年代的汇编语言是相当普遍的。例如,所有游戏机中使用汇编语言,因为可用内存量可能是少则几 KB。大量的代码在原 1984 年的Macintosh 是用汇编语言编写,以节省资源。
Fortran
而此时,大量的研究已经通过高层次的编程语言完成(意思是任何比汇编更抽象的东西)。
Fortran语言最初是由 IBM 公司在 50 年代开发的。
当时,创建语言的目的是专门解决一组特定的问题:Fortran 语言的目的是科学处理,它马上成为这一领域内占主导地位的语言,并在接下来的50年内取得巨大的成功。
它仍然是在高性能计算领域最流行的语言之一,而且作为基准,用于世界最快的超级计算机程序的语言的排名。
参考 http://en.wikipedia.org/wiki/Fortran
Translate
Fortran established the convention of using the asterisk for multiplication, which is still used today in virtually all languages.
Fortran 语言建立使用星号乘法,这是今天仍在使用的所有语言中的约定。
这是它的外观:
Program Hello
Print *, "Hello World!"
End Program Hello
这里有一个包含典型的 Fortran 程序的打孔卡片:
在打孔卡片上的 Fortran 代码。图片来自 Arnold Reinhold
COBOL
COBOL (COmmon Business-Oriented Language)
被设计用于商业用途。这是企图使编程语言更类似于英语,让程序员和管理人员可以读取它。
它的设计者有 Grace Hopper(发现 “Bug” 的人),以及发明了类似英语的数据处理语言 FLOW-MATIC 的人,也是最合适,帮助创建一个看起来类似英文通用商业语言的人选。
这是一个 COBOL 的 Hello World 程序:
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
ENVIRONMENT DIVISION.
DATA DIVISION.
PROCEDURE DIVISION.
MAIN.
DISPLAY 'Hello, world.'.
STOP RUN.
BASIC
BASIC (Beginner’s All-purpose Symbolic Instruction Code)
在 1964 由 John G. Kemeny and Thomas E. Kurtz
在 New Hampshire 的 Dartmouth College 设计
BASIC 是为分时专门开发。这是的 Fortran 的一个非常精简版本,以使其更易于编程。
它用了一个聪明的办法, 使用行号用于编程和其他操作,以及其他比如 GOTO 线跳跃操作。
在 70 年代中期和 80 年代,BASIC 版本是极为常见的,通常随 BASIC 直接在机器的固件微型计算机,使小企业主,专业人士,业余爱好者,和顾问,开发电脑,他们可以负担得起的定制软件。
基本催生了不同的语言,包括Visual Basic,是世界上最流行的编程语言很长一段时间,微软从微软BASIC创建的。
这是个简单的程序 (基于 GW-BASIC):
10 INPUT "What is your name: ", U$
20 PRINT "Hello "; U$
30 INPUT "How many stars do you want: ", N
40 S$ = ""
50 FOR I = 1 TO N
60 S$ = S$ + "*"
70 NEXT I
80 PRINT S$
90 INPUT "Do you want more stars? ", A$
100 IF LEN(A$) = 0 THEN GOTO 90
110 A$ = LEFT$(A$, 1)
120 IF A$ = "Y" OR A$ = "y" THEN GOTO 30
130 PRINT "Goodbye "; U$
140 END
ALGOL 60
ALGOL 60 (ALGOrithmic Language 1960)
是一个委员会推动的,非常好,有影响力的语言, 发布于 1960 年。
它从来没有得到普及,但它推出了许多重要概念,包括摆脱 GOTO。
在行与行之间跳来跳去行的语言,如 BASIC,难以遵循程序的流程,导致编写程序容易出错。
ALGOL 60 引入结构化程序设计和模块:它使用 BEGIN 和 END(因为大括号是不可用),感谢 ALGOL 60 现在我们有了代码块,而不是 GOTO。
ALGOL 也不希望太过专业,从而适合良好的科学和业务处理
下面是它的样子:
procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
value n, m; array a; integer n, m, i, k; real y;
comment The absolute greatest element of the matrix a, of size n by m
is transferred to y, and the subscripts of this element to i and k;
begin integer p, q;
y := 0; i := k := 1;
for p:=1 step 1 until n do
for q:=1 step 1 until m do
if abs(a[p, q]) > y then
begin y := abs(a[p, q]);
i := p; k := q
end
end Absmax
Pascal
Pascal 是在 1968 - 1969 年设计, 由 Niklaus Wirth 出版于1970年,其灵感来自 ALGOL
它最初是非常流行的,虽然最初设计为教学工具,很长一段时间很多人用它做通用编程。
但是,它不是模块化不够,有一些使得编程难的设计挑战。
比如有一个片段:
while a <> b do WriteLn('Waiting');
if a > b then WriteLn('Condition met') {no semicolon allowed!}
else WriteLn('Condition not met');
for i := 1 to 10 do {no semicolon for single statements allowed!}
WriteLn('Iteration: ', i);
repeat
a := a + 1
until a = 10;
case i of
0 : Write('zero');
1 : Write('one');
2 : Write('two');
3,4,5,6,7,8,9,10: Write('?')
end;
(其实我记得 Pascal 编程的时候我 14 岁,在学校,很酷)
B 在贝尔实验室开发于 1969 年, 它的灵感来自于 Fortran 和 BCPL。
B 基本上是 BCPL 系统精简掉任何汤普森认为他可以没有的组件,以使其符合当时迷你电脑的内存容量
http://en.wikipedia.org/wiki/B_(programming_language)
B 引入了 +=
操作符 (尽管写成 =+), 以及自增/自减操作符 (++
和 –
)
printn(n,b) {
extrn putchar;
auto a;
if (a=n/b) /* assignment, not test for equality */
printn(a, b); /* recursive */
putchar(n%b + '0');
}
C
C 诞生于 B 加上从 Pascal 加入一些好的想法。它是在贝尔实验室(再次)的 Dennis Ritchie 在 1969 年和 1973 年之间开发。
C是可能是最重要的语言在那里。这是令人难以置信的成功(和它仍然是)
此外,许多语言都基于C,包括:
C++ (1976)
Objective-C (1986)
Perl (1988)
Java (1991)
Python (1991)
JavaScript (1995)
PHP (1995)
C# (1999)
Go (2007)
...很多其他语言
Simula
挪威仿真语言Simula I 和 Simula 67 是语法上相当忠实的 ALGOL 60 的超集。
它的贡献是巨大的。Simula 基于 ALGOL 60 添加了对象,并因此被认为在第一门面向对象的编程语言。
Simula 67(发布于 1967 年)引入了对象,类,继承和子类,以及虚拟方法,协程,以及离散事件仿真。
如果这还不够,它的特色垃圾收集。 不错!
它看起来是这样的:
Begin
Class Glyph;
Virtual: Procedure print Is Procedure print;
Begin
End;
Glyph Class Char (c);
Character c;
Begin
Procedure print;
OutChar(c);
End;
Glyph Class Line (elements);
Ref (Glyph) Array elements;
Begin
Procedure print;
Begin
Integer i;
For i:= 1 Step 1 Until UpperBound (elements, 1) Do
elements (i).print;
OutImage;
End;
End;
Ref (Glyph) rg;
Ref (Glyph) Array rgs (1 : 4);
! Main program;
rgs (1):- New Char ('A');
rgs (2):- New Char ('b');
rgs (3):- New Char ('b');
rgs (4):- New Char ('a');
rg:- New Line (rgs);
rg.print;
End;
Smalltalk
Simula 对于 Alan Kay] 有巨大的影响, 他加入[施乐
在 1972 年他开始开发 Smalltalk
Smalltalk 的最初是专为儿童设计。它被彻底在真实世界测试和多次修改。它终于发布了第一个版本后 8 年正式发布,已经是好几代以后。
Smalltalk 的是一个伟大的语言,和第一个真正的现代面向对象的编程语言。
由于其难以把握的语法,它从来没有流行开来。然而,它的影响几乎所有的现代编程语言。的 Objective-C,C ++,Java 和 C#,Eiffel 和 Ruby 基本上都是 C 结合 Smalltalk 的。
示例显示 Smalltalk 中的 if
控制结构:
result := a > b
ifTrue:[ 'greater' ]
ifFalse:[ 'less or equal' ]
Self
受 Smalltalk 影响的另一种语言 -- 也是在施乐开发的 -- Self。
Self 设计为了性能。基于 Smalltalk 删除了类,使其更快。
不是使用类,而是用原型:Self 允许对象直接从其他对象继承,没有经过类。
你可能已经猜到了,有一门深受 Self 影响的语言是 JavaScript。
Scheme
Scheme 基于 Actor 模型。Actor 模型起源于1973年,当它被设想时还是一个激进的概念。它是在 LISP 实现,一门 MIT 于 1958 年创建的人工智能语言。
它包括尾递归,词法闭包,以及其他精彩的东西。
例如:
;; Calculation of Hofstadter's male and female sequences as a list of pairs
(define (hofstadter-male-female n)
(letrec ((female (lambda (n)
(if (= n 0)
1
(- n (male (female (- n 1)))))))
(male (lambda (n)
(if (= n 0)
0
(- n (female (male (- n 1))))))))
(let loop ((i 0))
(if (> i n)
'()
(cons (cons (female i)
(male i))
(loop (+ i 1)))))))
(hofstadter-male-female 8)
===> ((1 . 0) (1 . 0) (2 . 1) (2 . 2) (3 . 2) (3 . 3) (4 . 4) (5 . 4) (5 . 5))
E
E 是 Java 和 Joule 的结合,对于安全应用开发出一种语言。
基于 Actor 模型,它实现了对象能力模型。
def makeMint(name) :any {
def [sealer, unsealer] := makeBrandPair(name)
def mint {
to makePurse(var balance :(int >= 0)) :any {
def decr(amount :(0..balance)) :void {
balance -= amount
}
def purse {
to getBalance() :int { return balance }
to sprout() :any { return mint.makePurse(0) }
to getDecr() :any { return sealer.seal(decr) }
to deposit(amount :int, src) :void {
unsealer.unseal(src.getDecr())(amount)
balance += amount
}
}
return purse
}
}
return mint
}
JavaScript
...终于到它了
JavaScript 已经成为一个非常重要的语言。其在网络功能的设备无处不在,网络平台的支柱和基础,大多数 Web 和移动应用程序。多亏 Node.js 的,它在服务器上也是能运行。
JavaScript 基于 Java, Scheme, 和 Self.
它最初是在 Netscape 开发,希望实现类似苹果的 HyperCard,后者是为 Apple Macintosh 和 Apple IIGS 做的应用程序和编程工具,使得容易地构建应用程序,并添加到浏览器。
它的作者 Brendan Eich 希望其基于 Scheme,但 Netscape的管理思想,人们会不喜欢它的语法,并让他修改语法使其更类似于Java。
JavaScript 的借用 Java 的语法(只是因为它不得不),Scheme 的函数模型,以及 Self 的原型特性。
由于 Netscape 的处境,它在两个星期内实现并发布!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。