J9游戏|Home

国家高新技术企业
服务热线:400-6688-605
各种编程语言是怎么一步步进化的?
发布来源:J9游戏
发布时间:2026-05-2609:44

前两天看▽到一个帖★子,有人问:”Python 这么慢,凭什么火※成这样?”

很多回答:因为简单、生态好、AI时代的胶✦水语言……

这些说法❖都对,但全是果,不是因。

真正值得◉追问的是——Python 为什么被○设计成这■样?Guido van Rossum 当年做了❀哪些取舍,放弃了什⊕么,才换来了✫今天这个”慢但好用”的局面?

同样的问‣题可以问◥◥所有语言:C++ 为什么搞✦得这么复▪杂?JavaScript 为什么满✧地都是坑?Rust 为什么逼◎着你和编❀译器吵架?Go 为什么死✿活不肯加✪泛型(后来又加‣了)?

把这些问▼题串起来,你会发现▲一件事——今天所有►►主流编程〓语言的样❖子,都不是某✧个天才拍✩脑袋的产✩物,而是七十▪年来无数▾次设计博•丨弈的累✯积▸结果。

一场延续七十年的连锁反应

1957 年,IBM 的 John Backus 搞出了 FORTRAN。动机很朴✫素:用汇编写⊕科学计算◉丨太痛苦▿了,得让人写◤公式一样·写代码。FORTRAN 证明了”高级语言◣不比手写▲汇编慢多⊕⊕少”这件事,从此打开●了潘多拉盒子。

但 FORTRAN 的代码结※构是一团❋乱麻——GOTO 满天飞,变量作用∷域混沌,写到几千■行就没人○看得懂了。

于是 ALGOL 出来了。ALGOL 说:代码应该▲有块结构,应该有词▸法作用域,应该长得◎◎像数学一▪样优雅。ALGOL 自己没怎▪么流行,但它的设◈计思想渗▿透进了后※来几乎所⊙有语言。你今天写◉的花括号 {},缩进块,局部变量——根都在 ALGOL 那里。

C 语言呢?Dennis Ritchie 在贝尔实✧验室写 UNIX,需要一种”能摸到硬▪▪件但又不◉至于是汇✧编”的语言。BCPL 太粗糙,B 语言没有♦类型系统,于是 C 诞生了。C 的哲学极★其克制:信任程序✫员,不做多余◤的事。 指针随便⊙用,内存自己◈管,数组越界▵不检查——这在当年❀❀是优点,到了四十◤年后变成✩了无数安❉全漏洞的⊙根源。

C++ 是 Bjarne Stroustrup 的回答。他在剑桥►读博时用 Simula 写分布式♡系统的模♦拟程序,觉得面向○○对象好用⊙但 Simula 太慢;换成 C 写,性能上来○丨了但代◥码●结构乱得■一塌糊涂。“我想要 Simula 的抽象能▸力,和 C 的运行速丨度”——C++ 就是这句▣▣话的产物。后来 C++ 越长越大,模板元编▲程、多继承、RAII、移动语义……一层一层■往上堆。不是 Stroustrup 贪心,是真实工❉程需求在▹不断逼迫✦✦语言进化。

然后 Java 出来了。James Gosling 看着 C++ 那些让人△头疼的东✭西——手动内存▿管理、头文件、未定义行✩✩为——说不干了,我要垃圾♧回收,要虚拟机,要”写一次到◤处跑”。Java 砍掉了指✦针运算,砍掉了多•继承,砍掉了运▴算符重载,用约束换❀安全。代价是什◈么?啰嗦,慢,以及一个 AbstractSingletonProxyFactoryBean 级别的冗◎◎长命名传♡统。

Python 更激进。1989 年圣诞节,Guido van Rossum 闲得无聊,觉得现有⊕语言对非✿✿专业程序▵员太不友✪好了。他从 ABC 语言那里▪借来了强▪制缩进和✫简洁语法,从 C 和 Perl 那里借来★了实用主♢义,造出了一▾门”读起来像◇伪代码”的语言。Python 的核心赌❀注是:开发者的✿时间比 CPU 的时间值▹▹钱。 三十多年✧后看来,他赌对了。

再后来的◆故事你大►概听过——JavaScript 是 Brendan Eich 用十天赶❈❈工出来的,带着 Scheme 的函数式·基因和 Self 的原型继✯承,再套一层 Java 式的语法☆☆外衣,从此成为▹前端世界▪的独裁者✪和全栈世◥界的搅局◤者。Go 是 Google 三位老炮(其中有 Ken Thompson,C 和 UNIX 的共同创►造者)受够了 C++ 的编译速▸度和复杂·度后造的”反 C++“。Rust 是 Mozilla 的 Graydon Hoare 决心证明”不用垃圾※※丨回收也◆能•保证内存··安全”,用所有权△丨系统这·个∷激进方案○给出了自▾己的回答。

每一种语◦言都不是▣凭空蹦出·来的。它是上一◎代语言的✿痛点清单◢加上当时▼硬件条件✪和应用场◢景的交叉△△产物。

设计就是取舍,没有免费午餐

很多人评■价编程语★言喜欢说”XX 语言设计※得好”或”XX 语言设计★得烂”。这种说法▲大多数时♢候是不公○平的。

编程语言✦设计本质♧上是一道◦多目标优※化题,而这些目❋标之间经✪常打架:

性能 vs 安全性。 C 选了性能,结果你得◉自己保证▾不写出缓〓冲区溢出。Rust 说两个都♢♢要,代价是编✧译器像个❋严厉的老✧师,你的代码◦写法得服▹从所有权◆规则。Java 选了安全,代价是 GC 停顿和运►►行时开销。

灵活性 vs 可维护性。 Python 和 Ruby 极度灵活——运行时想⊙改类结构◤就改,猴子补丁❀随便打。小项目写♢着爽,大项目几•十个人协✧作,谁知道某◈个方法是△在哪被偷✫偷覆盖的?TypeScript 出来给 JavaScript 套上类型◣系统,本质就是▪在灵活性❋丨上做减❈法△△换可维护·性。

简洁 vs 表达力。 Go 的语法简▽单到有人▿丨说”无聊”,没有泛型(很长时间♢内)、没有异常、没有继承。Rob Pike 说这是特◇性不是缺❈❈陷——”少即是多,复杂性是✯敌人。”C++ 走另一个✩极端,模板图灵✧完备,你几乎可❈以在编译✩期干任何❈事,但也几乎※可以把任✧何同事逼◆疯。

这些取舍◆不存在标✯✯准答案。不同的时▪代背景、不同的应☆用场景、不同的设▹计者性格,会导向完◉全不同的◎选择。理解这一▣点,你看待编▹程语言的♢视角会完❖❖全不同——不再是”哪个语言◦最好”的宗教战◥争,而是”这个语言❈在哪些约▼束条件下◉做了什么✧取舍”的工程分♢析。

动态类型和静态类型之争:一场没有终局的拉锯

如果说编▲程语言领〓域有一场△打了几十◣年还没分❈出胜负的○丨战争,那就是动❉态类型和♧静态类型◤之争。

早期语言◣大多是静▴态类型的——FORTRAN、C、Pascal,你用变量◦之前得告★诉编译器○它是什么▽类型。这不是因✧为设计者▪喜欢麻烦✧✧人,而是当年❀的硬件资▴▴源太稀缺,编译器需▽要提前知▽道类型才▵丨能生成▿高△△效代码。

Lisp 是个异类。1958 年 John McCarthy 搞出来的◎这门语言◆◆压根不在·乎变量是◥◥什么类型——一切皆列●表,运行时再◥◥说。这种做法✪后来叫动►态类型。Smalltalk 继承了这▪个思路,Python、Ruby、JavaScript 进一步发⊕扬光大。

动态类型▼的爽感是•即时的:不用写类✫型声明,代码短,迭代快,原型开发★飞快。静态类型♡的好处是♦♦长期的:编译器帮❖你抓 bug,IDE 能给你精❀准的自动∷补全和重·构,大型项目·维护起来‣‣心里有底。

有意思的✧是,这几年两•个阵营在♢互相靠拢。Python 3.5 加了类型◇注解(Type Hints),TypeScript 给 JavaScript 穿上了类▼型盔甲,而 Kotlin 和 Swift 这些静态❋类型语言✦把类型推❖导做得极◎◎好,写起来几◆乎感觉不▿到类型声✪明的负担。

看起来势◢不两立的▵两条路,最后走着▣走着居然►越来越像❀了。 编程语言⊕的发展经◥◥常出现这◤种”殊途同归”的现象——表面上的✯分歧背后,其实是同▹一组基本∷矛盾在不❋同阶段的▼不同表达。


今天这些语言的样子,是历史的必然还是偶然?

两者都有。

必然的部〓分:硬件变了,需求变了,语言就得◤跟着变。1950 年代内存论 KB 算,你没法搞▲垃圾回收;2020 年代多核是☆标配,你不能不⊙考虑并发◥安全。从手动管▼理一切到∷自动化一▵切,从单机到♧分布式,从命令行✩✩到 Web 到移动端•到 AI——每次平台✧✧变迁都会▾催生新语○丨言或迫✩使▴旧语言大··改。

偶然的部✦分:如果 Brendan Eich 当年有两◉个月而不✦是十天,JavaScript 可能不会♧有那么多▸诡异的隐〓式类型转✧✧换。如果乔布♢斯没有回‣归苹果力❉推 NeXTSTEP,Objective-C 可能早就○消失了,也不会有◤后来 Swift 的故事。如果 Google 没有在 2014 年选 Kotlin 作为 Android 官方语言……等等,是 2017 年。但你懂我❋的意思——商业决策、个人偏好、历史机缘,这些”非技术因△素”对语言的▣命运影响◎巨大。

最耐人寻✯味的是,很多当年♢被认为”太学术”“太超前”的设计,几十年后✧变成了主◈◈流标配。ML 语言在 1973 年就有了类‣型推导和∷∷模式匹配,这两个特◢性 Rust、Swift、Kotlin 到 2010 年代才广泛※采用。Lisp 1958 年就有垃圾▾回收和函△数作为一■等公民,Java 1995 年才有 GC,Java 2014 年才有 lambda。Haskell 玩了几十✪年的 Monad 和纯函数,现在 Rust 的 Result 类型、Swift 的 Optional,隐隐都有❉那个影子。

编程语言⊕的演进从♡来不是线❋性的。它更像一♢棵不断分◆叉、嫁接、偶尔回溯●●的大树。


了解来路,才能看清去向

说了这么多,湖北网站⊙建设其实想表✧达一个观✿点:只学一门★★语言的语◆法是不够❀的。

知道 async/await 怎么写,不如理解·异步模型✯从回调地△△狱到 Promise 到协程的✯演进脉络。知道 Rust 的所有权·规则怎么○用,不如理解◇它为什么❖❖要在编译✦期解决 C++ 几十年没▴解决的内☆☆存安全问•丨题,以及为此❈牺牲了什◢么。知道 Go 不加异常☆处理是”设计决策”,不如理解 Go 的设计者♡从 C 和 Plan 9 一路走来,对”简单”二字有多▵▵执着。

这种理解〓不是靠读☆文档能获◣得的。它需要纵▣向——看到七十★年来这些▼语言之间‣的传承和▾断裂;也需要横✿向——把同时代、同领域的❋语言放在❋一起对照,看它们面♧♧对同一个⊙问题时做◥丨出了怎♡样▼不同的选▹▹择。