【编者按】本文是D语言联合创始人、架构师Andrei Alexandrescu在问答Quora上关于“在取代C语言的道路上,D、Go和Rust谁的前途最光明?为什么?”提问的回答,他从自己的角度谈及了D、Go和Rust在取代C/C++语言的优劣势,以及这三种语言的未来。
以下为译文:
作为D语言的联合创始人之一,尽管我的身份来回答这个问题显得有点不合适,但是我仍会尽可能客观地回答这个问题。我关注着Go和Rust的发展,同时我也知道D语言的缺点。在Go和Rust社区中,我一直鼓励同行的朋友分享他们的真实想法,所以在这里也一如既往。
首先,C++在这个问题上处在一个特殊的位置,无论它是否会像C一样被取代,亦或是成为替代C的语言,C++都是程序语言领域中的一个关键部分。
C++是最接近C的语言,安装配置的方式也明显相似,鉴于C++的年龄,下面我假设标题的问题也将C++语言列入替代C语言的语言列表中。
每一种语言都有一些它最根本的优势(我称之为“十倍优势”,指在这方面它比其他语言高几个等级)和一些它要面对的挑战。 这些语言的未来如何,以及它们是否能够取代C语言,取决于它们使用什么策略来利用好自己的“十倍优势”,以及它们如何克服他们所面对的各种挑战。
D语言
显然,这对于我来说轻车熟路,所以我知道如何在你面前秀出D语言设计的亮点之处,也知道如何带着你绕开D语言设计的不好之处。相比Go和Rust我更了解D语言,所以我可能会更多地去谈论D语言。坦白而言,D语言所面对的主要挑战是如下:
-
存在多年却一直没有被业界广泛采用。D社区内的一些业内人士有资格这样说(D当前还是相对比较年轻的一门语言,而且它的市场占用率也确实在逐渐增加),然而观念很难改变,同时观念也支配着市场占有率,因此管理者和工程师很难去接受一门在很长时间内都没有取得成功的语言,更进一步地说,如果短期之内D语言不能取得市场占有率的明显提升,那么时间的流逝将对D语言更加不利。
-
D语言同垃圾收集器的关系。GC是一项伟大的发明,但是将其用于D语言的决定使D远离了核心市场(也就是现有的C和C++开发人员)。对于C和C++程序员,历史悠久的主流思想是不使用GC,或者是在D中使用RAII或手工管理内存。尽管如此,由于标准库存对于其它的内存管理方式缺乏支持,以至于它形同虚设,需要用户自己去实现底层的基础设施,所以不使用GC而使用其它的内存管理方式在D语言中的意义不大。此外,对于那些愿意使用GC的人,其实现质量也是乏善可陈。整体而言,D持有由GC导致的缺点,却没有获得GC带来的好处。
-
缺乏远见。缺乏企业的支持,D一直是社区驱动,工程智慧比长期愿景更容易找到魅力和领导能力。在很长一段时间内,D的推广和公关做的都不好。第一个愿景文档(http://wiki.dlang.org/Vision/2015H1)是定在2015年1月1日,下一个迭代(Vision/2015H2 - DWiki)已经晚了4个月,持续了6个月的迭代周期已最好的讽刺。
当然D语言还有其它问题,但是它们要么由上面的问题所衍生,要么影响比较小。
我认为D语言的“10倍”优势在以下几方面(在接下的部分当我的说到"10x"时,通俗的理解是一个数量级):
-
同等规模的代码,D语言的编译速度比C++快。编译速度上的差距对于C++而言根本就不可能弥补,其他语言要想追赶上D也是比登天还难。(Go的编译速度比D略微快一点,但是生成的代码运行效率更慢一点)使用系统级的语言快速的构建代码,这是一种具有深远意义的变革。D语言的高度抽象能力使它成为编写高度优化代码的一很好的选择,因为实验成本很低。
-
比同等开发效率的脚本语言快。使用D语言的一个好处是可以像使用脚本语言一样便利地去处理各种日常的事务。构建/运行的过程非常快,并且速度的提升是非常明显的,同时D语言没有“碰壁效应(hitting the wall)”,如果脚本变得非常巨大,D总是有其它的如模块化这样的机制来提供对于速度优化的支持。当然,这种比较前提是基于相似的颗粒度,像Python有更多的可直接使用的库资源,但是一个数量级的差距是根本存在的:系统级编程语言很难达到D语言的水平,而脚本语言又无法在速度上缩小与D语言的差距。
-
与C和C++的交互比其它语言容易。D使用与C和C++相同的内存布局,它所做的一切其它的工作都是建立在这个基础上,同时底层能做到零开销读取。整个C标准库都可以在不做特殊的语法处理的情况下实现无运行损耗的去访问,对于C++标准库要达到同样的支持,还有一些工作要做,还有许多C库可以直接支持(https://github.com/D-Programming-Deimos),甚至可以这样说,没有其它语言能够达到D语言的集成水平。
-
在泛型编程方面比其它系统级语言好。D语言的静态内省、编译时计算、minedin-deriven代码生成构成一个强大的组合,而这在其它语言里是很难正确做到的。在这方面,Go没有任何深度,因为它直接不提供这个功能。C++17也绝望地迷失了方向,Rust则是刚刚企图涉足。
Go语言
申明一下,下面都是我的个人观点。我认为Go语言要面对以下挑战:
-
由于间接调用和垃圾回收机制而导致的根本性缓慢。Go语言的一个核心特征是不借用间接的函数调用和垃圾回收机制几乎无法写出有意义的代码,而这也正是Go在实现核心性能道路上所面对的主要障碍,Go团队对于这一点作出的应对是战术性的,例如他们采取的措施是在实现更好的垃圾收集器方向展开工作,但是我认为Go对C的这种战术性的挑战是很难取得成功的。
-
政治。Go所走的路线在一些问题上持有极其强硬和死板态度,这些问题有大有小。在比较大的方面,泛型编程被严格控制,甚至贬低到只有"N"个字;有关泛型编程的讨论都是试图去劝阻任何有意义的尝试,这已经足够让人觉得耻辱。从长远来看,技术问题的政治化是一种极其有害的模式,所以希望Go社区能够找到修正它的方法。
-
从简单到简单化。Go是出了名的简单,有很多人们快速学习使用它的事迹。然而随着时间的推移,这也同样成了一个问题。Go程序员是没有希望的过路人,他们发现自己一次又一次写着相同的东西,由于Go甚至无法对最简单的概念和算法进行抽象。没有被库很好地支持的区域是很难进入的,这在使用Go开发了一个项目并永远不再想使用Go的开发者中是一个强烈的反映。如果Go能够使开发中的“回头客”过的更好,那将是非常伟大的。
在我看来,Go语言的十倍优势如下:
-
策略更好。在短暂的定位于系统编程语言之后,它将自己定位于网络基础服务设施领域,这是一个明智的营销举措,结合了Go团队的技术优势(这个世界上最好的网络服务开发工程师),作为一个市场热点,网络服务开发领域一直被JavaEE和其它一些缓慢的脚本语言统治着,Go为这个领域带来了一股新的气息,现在Go是这个领域的一个主要成员,并且它的地位很难被取代。
-
工程性好。Go的背后有一个坚实的工程技术团队,他们保证了Go语言,以及其网络库和工具的质量。直到目前为止,良好的工程性已经弥补了Go语言本身的很多不足之处。
-
品牌好。我们中的很多人都得承认Go的一个重要推广因素是它与Google的关系,这使得人们对于它的专业性、质量和稳定性有更多的信心。当然品牌不是万能的,但是那意味着Go只需要成为一个体面的语言,它不需要成一个“梦幻”般的语言,因这品牌会去帮助它推广。
Rust语言
让我再次强调一下,这只是我的个人看法。我认为Rust面临着一些有趣的挑战:
-
一个不和谐的特性。阅读任何数量的Rust代码都能让人想起这个笑话“朋友们不要让朋友跳腿日”和体格强壮的男人躺在廋腿上休息的漫画形象。Rust把安全、精确的内存管理作为一切的中心放在首位。不幸的是,这在其他语言中几乎都算不上问题。它意味着思考和编码的工作的很大一部分内容将是致力于一份类似文职的工作(而GC却可以让这一部分内容自动淡出人们的视线),安全、确定地进行内存回收是一个困难的问题,但并不是唯一的问题,在编程中它也不是最重要的问题。因此,Rust为解决这个问题花费了不成比例的语言设计成本,有趣的是Rust在其他方面也慢慢成长起来。让Rust在个性上更和谐的唯一解决方案是在语言发展的过程中,引入其它抽象机制来帮助解决烦人的资源管理的问题。
-
另类的语法。Rust的语法比较独特,但是这种语法的差异并没有明显的优势,它的语法让来自于Algol语法风格的人们觉得非常难受。
Rust的十倍优势如下:
-
理论优势。在三个语言中,Rust是唯一的由世界级PL理论家领衔的语言,这可以通过其语言的精确定义和其技术方法的深度得到验证。
-
安全性好。当然我前面只是讨论了一下这样做的成本。
-
公关好。当Rust在社区中深受喜爱和几乎不会出错时,pre-1.0已经有很长一段时间了。无论什么时候出现问题,Rust要么自己解决,要么通过1.0解决。1.0的发布结束了Rust和大众的蜜月期,据我的测量和评估,人们对于Rust的普遍热情会有一定程度的下降,但是Rust终究是一门体面的语言,它有实物来应对并且建立一个良好推广模式。
总结
哪一种语言都能取代C、C++,亦或者是共存,甚而哪一种语言更好,但大多数情况下,在实际的项目中都还是默认选择了C或者C++,至于哪一种语言是项目的更好选择,这取决于几个语言在项目中的特有长处。