当代编程语言简评

著名大喷子王垠最喜欢点评各种语言的优缺点(当然基本上都是缺点居多),作为技术人也写一篇东西表达一下自己的看法。

原初

C和Lisp是流行至今的最古老的两门编程语言,从一开始就走向了不同的道路。

C:高效、简洁,直接操控内存和cpu,面向机器
Lisp:抽象,强大,但是效率不高,gc语言,面向业务

从这时候开始,语言演化就是在这两门语言的基础上取长补短

C -> ObjectC/C++ -> Rust

C++完全兼容C90,这是它成功的原因,也是它失败的原因。

C++最开始就是C with class,随着OO的流行,C语言抽象能力不足的问题越来越明显。于是C++之父往里面塞入了类,以及随之而来的各种概念。后来,又加了模版,于是才有了STL。

C++非常复杂,包含了各种流行的编程范式。抽象能力得到了巨大的补充,但是并没有引入GC,仍然坚持zero-cost abstraction。虽然后来在C++11中引入了智能指针,但是已经有一些积重难返的感觉了。

OC也是C的超集,设计的更加不爽了,苹果自己也想要用Swift替代之。

Rust也坚持零成本抽象,但是它另辟蹊径,从语言和编译器层面上试图解决内存问题,引入了生命周期、各类指针等各种复杂的设计。Rust有现代语言完善的包管理系统,这是比C++好的地方,但是它试图解决问题的手段有些奇怪,有时候有一些因噎废食的感觉。这也是我不太看好Rust流行的原因。真正的高手,用Modern C++就够了。

Smalltalk -> C#/Java -> Scala -> Kotlin

和C同时期的OO语言,最出名的是Smalltalk(lisp并不是OO语言,它可以抽象出一切,Smalltalk的诞生也是受了lisp的影响)。Java的创造者受够了C++的复杂,决定另起炉灶融合Smalltalk和C++的长处,做出一门新语言。

Java是工业界长时间以来最流行的语言,虽然C#改进了Java,并引入了linq等方便至极的语法,但是.net core开源的太迟了。

Java太OO了,这是它成功的地方,也是它失败的地方。Java的流行导致所谓设计模式的泛滥,Java的抽象能力过于局限于OO,导致很多本来很简单的东西写起来复杂无比,Spring这类框架的流行本质上就是在弥补Java语言的缺陷。

Java7以前的Java足够简单,这为业界量产初级程序员打下了良好的基础。

Scala是一门学术语言,类似C++,它过于复杂,所以不可能得到流行。Kotlin就好得多,它语言特性优越,并且积极演变。唯一的问题是,它必须运行在jvm上,那到头来你还是承受Java的历史遗留问题。

Python/Perl/Ruby/Javascript

虽然动态语言当初走的是完全不同的道路,到最后也慢慢引入类型化,比如Python3也开始支持类型注解,毕竟编译器还是能帮上很多忙的。

动态语言在开发速度上无与伦比,所以更适合用来搭原型,写脚本。对于I/O密集型工程,也可以选择他们快速开发。

JS的流行是一个历史上的错误,别的没啥好说的了…

Erlang/Go/Swift

Erlang是一门分布式设计语言,它纯粹为了解决工程问题而生,它正确而强大。但是,它的生态不够开放,语法也略显怪异,效率上也不是很尽如人意,所以最终未能大规模流行。

Go在分布式上做的没有Erlang那么激进,netchan这玩意儿最终还是没有内置到语言里。不过Go的优势是足够快,足够简单。

Swift目前还是主要用作客户端开发,但是已经开源。啥时候引入async/await以后,也可以用来做服务端开发,可惜没有生态。

Haskell/OCaml/F#

函数式编程语言过于学院派,有一种学之则生,用之则死的感觉,如同Lisp一般。

不过,他们有一种数学美。

PHP

PHP没啥好说的,在HTML里面写代码决定了这玩意儿的用处太受限了。如果不是Facebook抱残守缺,早就应该被淘汰了。

最好的语言

后端来说,目前就是Java,但是Go2有希望超越。

顺便说一句,我可不喜欢Java了,我宁愿选Go1。

题外话

历史并不能给人们以教训,人们总是犯同样的错误。

C++引入模版,Java和.NET都是半路引入泛型,Go却还要重滔覆辙。C++开始就用异常代替了错误码,Go非要到Go2再还这些技术债,这是何苦。