作者apenwarr。
译者童方岩
我画了一个主流编程语言的过渡图,展示了程序员在不同语言之间的切换路径。
至于编程语言,有许多类似的图形来显示它们的相互演化。但我并不想从语言设计者的角度去解释这个问题,而是想从程序员本身的角度去看待语言进化。虽然它们之间有一些相似之处,但并不完全相同。
从这个图可以看出,如果开始使用编程语言A,接下来最有可能切换到哪种语言。这种猜测不太科学。但是如果你需要精确的科学,你不会在这里读这篇文章吧?也许这个流程图能为我揭示更多。
免责声明:在这种情况下,不考虑程序员最喜欢的语言。人们可以在任何两种语言之间切换,也可以学习多种语言,然后选择最适合自己工作的语言。本文的观点具有一定的倾向性。
在接下来的几页中,我所有的陈述都是个人观点。为了不影响读者阅读,他们不会一一陈述。
程序员迁移模式
我想强调最常见的“终极节点”。在这些节点上,人们在他们的维度上找不到更好的替代编程语言。终极节点包括:Rust、Java、Go、Python 3、Javascript和node.js..
几年前,我以为C也是一个终极节点。也许我们现在还可以这么想,因为有很多重要的项目还在用C,可以认为是不可替代的。然而,有迹象表明C是可以被取代的。我最喜欢的例子是有趣的空指针。Linux内核有一个编译器带来的致命弱点,那就是NULL值是“不可能”的,所以函数是不用空指针检查的。c语言也是一团糟,它的规范中有几个新的编程语言没有的致命错误。也许有一天这些错误可以被修正。
让我们后退几步。如果从顶层开始,根据进入编程的人的不同规格,可以看到四个主干:
“低级”编程,包括asm和C..
“商业”或“学习”编程,从BASIC开始。
计算/技术编程,如Fortran、MATLAB和r。
脚本/胶水编程,如shell和perl。
这将帮助您更好地理解代码。)
不管怎样,让我们回到90年代。当时假设编程世界非常简单,初级程序员使用C、asm或Turbo Pascal,商业程序员使用VB,数值计算器使用Fortran、R或MATLAB,胶水程序员使用sh或perl。
当时,编程语言被如此严格地划分。直到画了这张图,我才意识到这一点。显然,我们不能用perl写操作系统内核,用MATLAB写胶水程序,用VB写大型矩阵乘法算法。
现在变化很大。语言的选择不再像过去那样清晰。
语言的变化主要是风格的变化
让我们从树的开头开始。用Asm编写程序相当困难。但是即使是现在,它仍然是编写一些程序的最好方法。无论是在App Store还是手机上的JIT,每种编译语言最终都会把代码编译成汇编或机器语言。
基于asm,有两个分支:C型分支和Pacal型分支。
Pascal风格的分支语言的特点是“开始……结束”。c语言的特点是括号。当然,C语言影响了很多编程语言,图中并没有体现出来。因为我们说的是程序员,不是语言设计师。
先看c。奇怪的是,一旦人们开始使用C,他们就习惯于处理各种情况。无论是好是坏,它都是为数不多的能够合理实现所有四种编程问题的语言之一。这四种类型比较难,但是C可以处理,速度还可以。
如果你是C程序员,接下来你会用哪种语言?这取决于它是用来做什么的。
显然,C++是一个选项。虽然它的名字类似语法和C,但与C风格有很大的不同。除了BeOS,其他操作系统内核都不会使用C++。在使用潜在的Rust之前,操作系统基本上是用c编写的。
但是从事商业和数值计算的人喜欢C++。说他们喜欢可能不准确,但是他们别无选择,只能用C++。
对于胶水程序,很多人会直接从C到python 2。我最近做过这个。与perl不同,Python 2类似于C语言风格,语法更简单。C程序员很容易理解python C模块。从python调用C函数比其他语言更简单。如果在Java中调用,需要处理非引用计数的垃圾收集问题。Python的“os”模块提供了C系统调用和调用可以工作的环境。程序员可以用C语言访问错误代码,并设置相应的信号处理程序。唯一的问题是python有点慢。但是,如果只把它当作胶水语言,就可以忽略python的慢。速度慢的时候可以写C模块或者调用C库或者子程序。
此外,Java出现后,很多C和C++商业软件的程序员很快就转向了Java。C++编译时间长,头文件多,可移植性差,发布后重复使用的错误问题。因此,虽然Java运行缓慢,但人们更喜欢使用Java。
记得有一篇文章说,Go的设计师最初以为Go可以和Java或者C++相比,但实际上并没有做到。爪哇就像一个著名的酒店或门罗公园。一旦你入住,你就不想离开酒店。同时,程序员没有从C++转到Java主要是因为:a)Java比C++慢,b)Java仍然存在垃圾收集的经典问题。
Go在之前切换到python 2的glue程序员中很受欢迎。原来,python速度慢是它的痛点。随着计算机复杂度的快速增加,python胶水程序的规模越来越大。与其优点相比,动态类型带来了更多的麻烦,因此人们开始使用预编译二进制。Python 2占用大量内存,所以Go对其RAM进行了改进,避免了从C++迁移到Go带来的问题。Go几乎和python一样难,但它运行更快,占用内存更少。
我们现在称Go为“系统”语言,因为当我们谈论glue程序时,我们会更多地想到perl和ruby,但它们具有相同的功能。Go是一种粘合剂,可以将各种成分组合成一个系统。
赫尔斯伯格因素
我们来看看Visual Basic和Pascal的分支。人们有不同的想法:明显正确或明显错误。上世纪八九十年代,还是有人认为编程应该方便初学者,所以在个人电脑上预装了免费的编程语言,大部分是BASIC。
另一方面,大学教编程时,避开BASIC,不选c,他们更喜欢Pascal,认为Pascal容易学。正如Algol的学术论文中提到的,它的语法适合教学,每个学生都能理解。因此,有学术分支和个人电脑分支,但它们有一个共同点,那就是都不同于c。
基于PC的BASIC演变成了基于Windows的Visual Basic,这可能是javascript出现之前最流行的编程语言。
与此同时,帕斯卡也在尝试切换到PC。Turbo Pascal因其外观而流行,一度成为最快的编译器。帕斯卡没有夸大速度。甚至有些C程序员喜欢用Pascal,并不是因为喜欢它类似C的语法,而是因为它速度快。
当时“商业”发展有两个分支:BASIC和Pascal。随着Windows的出现,Visual Basic出现了。基于DOS的Turbo Pascal有点过时,基于WIndows的Turbo Pascal也不突出。为了竞争,涡轮帕斯卡的设计师安德斯·海尔斯伯格创造了德尔菲。Delphi和Visual Basic一样,有可视化的编程环境,但都是基于Turbo Pascal语言,很少出现实时动态链接库找不到或者匹配不到的恼人问题。
Delphi不错,但不属于微软。加上商业因素,情况变得有些困难。在经历了一系列意想不到的事件后,赫吉尔伯格离开了微软,而是继续开发C#,发布了微软。NET平台,并包括视觉Basic.Net。据说C#统一了这两个分支。
不幸的是,如前所述,VB.NET很可怕。它与Visual Basic几乎没有任何共同之处,而更像是C++的一个慢版本,它覆盖了一些非典型的基本语法和更糟糕的UI设计工具。C#也不是Delphi。然而,这些语言已经消失了,微软已经尽了最大努力来促进这一点。
不知道怎么被称为Visual Basic程序员。微软承诺让他们转投VB.NET,但大多数人不愿意。我想画一个“他们的实际选择”的箭头,但老实说,我不知道该指向哪里。也许他们成为了网络开发人员或者编写了Excel宏。
从现在开始,写基于的Windows软件很有意思。微软推广的. NET平台。可能使用的语言深受赫尔斯伯格的影响。在反击之前,hejsberg的语言被微软和Visual Basic压制,所以hejsberg转而编写Typescript,这将在后面讨论。
胶水语言简介
最初的胶水语言是Unix shell,它也以引入“管道”的概念而闻名。管道连接简单的工具来完成复杂的任务。
啊,那些日子,那些日子一去不复返了,perl是献给他们的悼词——罗布·派克
事实证明,设计小而简单的工具很难,我们通常没有足够的时间来做这件事。越来越流行的是,我们可以跳过这些可移植的工具,全身心地去写奇怪的语言,这些语言会粘上很多乱七八糟的小程序。
第一个是awk,这是一种语法类似于c语言的解析语言,可以在shell管道中使用。当时用一种语言的一行用另一种微语言有点奇怪。幸运的是,我们已经习惯了,因为今天的网络程序是这样的。
Perl是下一个。Awk没有足够的标点符号,这导致了Perl。
Perl从perl 5开始,变得越来越流行。现在,Perl已经停止改进其语法,并尽一切努力在perl 6上从头开始构建它。
这种配置会在几个方向上留下空的“粘合”故障。如果程序员认为perl的语法很差,他们可能会改用python。如果他们认为perl的语法神奇而有效,只需要做一些调整,他们可能会转向ruby。如果使用perl来运行web的CGI脚本,它可能会保持原样,或者改用PHP。
Ruby很快成为网络服务器支持的语言。Python也在不断发展。
现在有趣的是,整整一代程序员放弃了命令行方法,希望在web端做任何事情。在某些方面,这更好,例如,一个胶合程序可以超链接到另一个胶合程序。另一方面,更糟糕的是,因为现在所有的网络程序都很慢,它们不能使用脚本,并且需要500MB的RAM 空来安装另一个副本的Electron。这就引出了网络语言的话题。
网络语言
在图中,有许多箭头指向javascript的“胶水”分支并不奇怪。Javascript最初只在前端使用。当node.js出现时,这种情况完全改变了。现在,您只需要学习一种语言来编写前端、后端和命令行工具。Javascript最初被设计为最终的胶水语言,试图集成HTML、CSS、面向对象编程、面向函数编程、动态语言、JITs以及其他一切可以通过HTTP请求获得的东西。
但这并不好,因为向后兼容性对web的成功非常重要。为了确保这一点,我们不能修复一些严重的错误。1995年,经过10天的设计,Javascript发布了。对于10天的成绩来说,是相当优秀的,但同时也存在一些问题,无法修复。
这是图中唯一有双箭头的地方:在javascript和python 3之间。我们称之为脚本语言的阴阳两面。
大多数已经出现的glue +web语言正在消失,python不在其中,至少现在还不在。我猜是因为python本身是有道理的。如果长时间使用javascript编程,一段时间后就会变得不正常。这时,为了缓解压力,程序员可能会改用python。
同时,如果你长期使用python,当你终于准备好编写一个web应用程序时,前端代码和后端使用完全不同的语言是很烦人的。一个语法是。连接,而另一个变成“,”。加入,这让人们完全无法记住谁是谁。
一种语言有JIT,它一旦运行就能变得很快。另一种是快速启动和慢速运行。
一个有合理的命名系统空,另一个没有。
不知道从长远来看python 3能否打败javascript。但至少目前不会被打败。
与此同时,对编程的事实分支不满意的Hejlsberg看到了javascript中的许多问题,并引入了TypeScript。与此同时,微软突然停止推广Windows应用,开始大规模推广web和开源。这意味着微软首次将开发者推向网络语言javascript。在此基础上,他们有自己的TypeScript,我认为这是一种很好的语言。这个分支已经存在了几十年,开始和它的分支合并,可能很快就会消失。
TypeScript能战胜javascript?这是一个有趣的问题,我不知道。我曾经赌赫伊斯伯格赢,但我通常很容易输。
Python 2与Python 3的比较
综上所述,我对python 2和3有一个结论。他们相似,但不完全相同。我认为这是因为他们在整个程序员的语言迁移图中处于不同的位置。Python 2开发人员来自C和perl开发人员,希望编写胶合代码。Web服务器是稍后添加的应用场景。我的意思是,网络程序在python 2出现后变得流行并不奇怪。许多python 2开发人员转向Go开发,因为他们想要编写的一些“系统胶水”代码正好适合使用Go。
Python 3的开发人员切换了不同的语言。事实证明,自从python 3问世以来,python的使用有了很大的发展,但新人们与以前的人们不同。借助SciPy和Tensorflow模块,很大一部分新程序员从科学和数值处理领域转移过来。老实说,Python在高通量数值处理中是一个相当奇怪的选择。然而,这些库的存在是我们选择它的原因之一。我猜python的另一个优点是它很容易与C模块集成。当然,python 3本身就是网络编程。
要理解python 2和Python 3之间的区别,只需看看它们不同的字符串类型。在Python 2中,字符串是一组字节,因为操作系统、Unix管道处理和网络套接字处理都是以字节为单位的。Python 2是系统程序的胶水语言,其处理以字节为单位。
在python 3中,字符串是一组unicode代码。因为人们不擅长unicode代码转换,而且在与网络交互时,都是基于unicode的。做科学数值计算的人不在乎字符串,而做网络编程的人更在乎unicode,所以python 3用的是unicode。如果你想用python 3写一个系统程序,你总是会厌倦unicode转换,甚至最简单的文件名都需要转换。这恰恰是因为有原因,也有后果。
https://apenwarr.ca/log/20190318
单击一个可以少看到一个bug