现在的位置: 首页 > 编程语言 > 正文

关于编程语言及程序员迁移模式

2019年12月12日 编程语言 ⁄ 共 3184字 ⁄ 字号 评论关闭

  关于编程语言,还有很多类似的图可以表示它们相互之间的演进。不过我并不想从语言设计者角度来说明这个问题,而是想从程序员本身来看待语言演变。虽然两者间有些接近,但并不完全相同。

程序员迁移模式

  我想强调下最普遍的“终极节点”。在这些节点上,人们在他们所处的维度找不到更好的可替代编程语言。这些终极节点包括:Rust、Java、Go、Python3、Javascript和node.js(node.js作为一种特殊的Javascript,在这里特别指出)。

  几年前,我认为C也是一个终极节点。可能现在也还可以这样认为,因为有大量的重要项目(如OS内核)仍使用了C,而且可以认为它无可替代。不过有迹象表明C其实是可以替代的。我最喜欢的例子就是有趣的空指针。Linux内核有个编译器带来的致命弱点,即NULL值“不可能”出现,因此没有对函数进行空指针检查。C也是一团糟,其规格里有几个新编程语言所没有的致命错误。也许某天这些错误能被修复。

  让我们回退几步。如果从顶部开始,根据人们进入编程的不同规格,可以看到四个主干:

  “低级”编程,包括asm和C。

  “商业型”或“学习型”编程,从BASIC开始。

  计算类/科技类编程,如Fortran,MATLAB和R。

  那时,编程语言就是这么严格划分的。画该图时,我才意识到这一点。显然,我们不会用perl来写操作系统内核,不会用MATLAB来写胶水程序,不会用VB来写大型矩阵相乘算法

  现在则变化很大。选择什么样的语言已经不再像过去那样明确了。

语言的变化主要是风格的变化

  我们先来看树起点asm(汇编语言)。用Asm来写程序是相当困难的。不过即使到现在,它仍是写某些程序最好的方式(如电脑启动后的最初几个指令,或是中断处理的入口代码)。不管是在AppStore里还是手机上的JIT里,每个编译语言最终都会将代码编译成汇编或机器语言。

  基于asm,出现了两个分支:C类型分支和Pacal类型分支。(Algol出现的更早,不过此处忽略掉。宣称自己是Algol程序员的人并不多。Algol对其他语言影响很大。)

  Pascal风格分支语言的特点是有"begin…end"。C风格语言的特点则是有括号。当然,C影响了很多的编程语言设计,这点在图中没有体现。因为我们现在讨论的是程序员,而不是语言设计人员。

  首先来看看C。很奇怪,一旦人们开始使用C,就习惯用它来处理各种情况。不管实现优劣与否,它是为数不多的能合理实现所有四类编程问题的语言之一。这四类都有些难度(除了低级编程,它正是C擅长的领域),不过C都能搞定,速度也还可以。

  如果你是个C程序员,接下来会使用那种语言呢?这取决于用它来做什么。

  显然,C++是一个选择。虽然其名字与语法和C很像,但它其实和C风格迥异。除了BeOS,其他操作系统内核不会使用C++。在极具潜力的Rust使用前,操作系统基本都使用C编写。

  但是商业(“大型程序”)和数值计算(“快速程序”)领域的人员喜欢C++。说喜欢不一定准确,但他们别无选择,只能使用C++。

  对于胶水程序,很多人会直接从C(或C++)转到python2。我最近也这样做过。和怪异的perl不同,Python2类似C语言风格,其语法更简单。C程序员很容易理解pythonC模块(并可以编写新的python模块)。从python里调用C函数比其他语言更简单。如果在Java里调用,就需要处理非引用计数的垃圾回收问题。python的“os”模块提供了C系统调用及该调用能工作的环境。程序员可以访问C语言中的错误码并设置相应信号处理程序。唯一的问题就是python有些慢。不过只把它作为胶水语言,则可以不考虑python的慢速。速度慢时,可以写C模块或调用C的库或子程序。

  另外,Java面世后,很多C和C++商业软件的程序员非常快地切换到Java。C++编译时间长,头文件繁多,可移植性差,有释放后重用的错误问题。因此,虽然Java运行的很慢(和python不同的是,Java宣称“理论上运行很快”),人们还是更愿意使用Java。

  Go在之前已经切换到python2的胶水程序人员中流行起来。事实证明python的慢速是其痛点所在。计算机复杂度急剧增加,python胶水程序规模也越来越大。相较其优势,动态类型带来的麻烦更多,因此人们开始使用预编译二进制。python2占用很多内存,因此Go做了RAM改进,避免了从C++迁移到Go带来的问题。Go的难度和python差不多,但它运行更快,占用RAM更少。

  我们现在称Go是一种“系统”语言,因为提起胶水程序,我们更多的是想到perl和ruby,不过它们的作用是一样的。(试试告诉一个C语言内核开发者,Go是“系统”语言,看看他们的反应)Go是粘合剂,可以把各个组件组合到一起成为一个系统。

胶水语言的简要介绍

  最初的胶水语言是Unixshell,它因引入“管道”概念也很著名。“管道”连接简便的工具来完成复杂的工作。

  啊,就是那些日子,那些日子一去不复返,perl就是献给它们的悼词–RobPike

  事实证明,设计小而简单的工具是困难的,通常我们没有足够的时间来做这个。能够让我们跳过这些轻便工具,致力于编写奇特的、能够粘着很多乱七八糟的小程序的语言变得越来越流行。(它对shell语言的缺陷,尤其是与引用和通配符扩展规则相关的缺陷并没有帮助。)

  第一个是awk,它是语法和C类似的解析语言,可以用在shell的管道上。那时,在一种语言(sh)的一行中里使用另一种微语言(awk)有点奇怪,庆幸的是我们适应了,因为现在的web程序都是这样的。(我们略过csh,它是另一种与C语法不兼容的语言,存在不同的致命缺陷,可以被sh替代。)

  接下来是Perl。awk没有足够多的标点符号,从而促成了Perl的产生。(好吧,这只是个玩笑。)

  Perl开始到perl5,越来越受欢迎。现在,Perl停止改进语法,在perl6上倾尽全力,从零开始打造。(在图中并没有标出perl6,因为还没有人切换过去。)

  这样的配置给在几个方向断层进行“粘合”留下了空间。如果程序员觉得perl的语法差劲,可能会切换到python。如果他们认为perl的语法很神奇有效力,只需要一些调整,则可能会切换到ruby。如果使用perl来运行web的CGI脚本,则可能会保持原样,也可能会转而切换到PHP。

  ruby很快成为web服务器支持的语言(进而是RubyonRails)。Python也同样在演进。

  现在有趣的是:整整一代程序员摒弃了命令行方式(这也是胶水语言运行的方式),希望在web端可以做任何事情。从某方面来说,这样更好,比如在一个胶水程序中可以超链接到另一个胶水程序。从另一方面来说,则更糟糕,因为现在所有的web程序都很慢,不能使用脚本,而且安装Electron的另一个副本需要500MB的RAM空间等等。这就引入了web语言这个话题。

Web语言

  图中,集中在javascript的“胶水”分支有很多的箭头指向,这并不奇怪。Javascript最初只使用于前端。当node.js出现后,这种情况完全改变了。现在,只需要学习一种语言来写前后端和命令行工具。Javascript最初的设计是将其作为最终的胶水语言,试图融合HTML、CSS、面向对象编程、面向函数编程、动态语言、JITs以及其它一切能通过HTTP请求得到的东西。

  但是这样不太好,因为后向兼容对于web的成功至关重要。要保证这一点,就无法修复一些严重错误。1995年,经过10天的设计,Javascript发布了。对于10天的成果而言,它相当优秀,但同时它也存在一些问题,无法对其进行修复。

  

抱歉!评论已关闭.