没人能比D语言的共同设计者以及绝大部分D语言库的实现者Andrei更了解D语言

图像说明文字

Scott Meyers 世界顶级的C++软件开发技术权威之一。著有两本畅销书Effective C++和More Effective C++,曾经是C++ Report的专栏作家。他经常为C/C++ Users Journal和Dr. Dobb's Journal撰稿,也为全球范围内的客户做咨询活动。

图像说明文字

Andrei Alexandrescu 世界顶尖的C++专家,2001年撰写了经典名著《C++设计新思维》(Modern C++ Design),曾荣获2001年最佳C++图书称号,书中所开发的Loki已经成为最负盛名的C++程序库之一。他被认为是新一代C++的代表人物,因为对Template技术的精湛运用,震撼了整个C++社群,开辟了C++编程领域的“Modern C++”新时代。他还与Herb Sutter合著了《C++编程规范》(C++ Coding Standards)。他花了8年的时间攻读机器学习方面的博士学位,专门研究部分自然语言处理结构。自2006年开始,他与D语言的最初设计者及实现者Walter Bright紧密合作,设计和实现D语言及其标准库,他是D语言很多特性的设计者,也是大多数D语言标准库的作者。Andrei Alexandrescu在工业界和学术界都有很高的声誉。现为Facebook研究员。

不管从哪个方面来讲,C++都获得了巨大的成功,但即使是其最狂热的拥护者也不可否认它是一只复杂难懂的“猛兽”。这种复杂性也影响到了被广泛使用的C++后继者Java和C#的设计。这两种语言都在尽量避免C++的复杂性,采用的方法是,通过一个更易使用的程序包提供其大部分的功能。

降低复杂性可以采用的基本形式有两种。一种形式是,去掉“复杂的”语言特性。例如,通过垃圾回收(garbage collection)的方式可以避免C++中对手动管理内存的需要。在模板的“成本/效益”测试被认定为失败时,这些语言的初始版本都选择了排除C++中与泛型支持相关的所有内容。

降低复杂性的另一种形式是,使用相似但要求更少的结构方式取代“复杂的”C++功能。C++的多重继承可以改变成使用接口进行扩展的单继承。Java和C#的当前版本都支持模板化的泛型,但它们都比C++的模板更简单。

这些后继语言并不只是要求通过降低复杂性来完成C++所能完成的任务,而是被寄予了更多的期望。它们都定义了虚拟机,增加了对运行时反射(runtime reflection)的支持,并提供了大量的开发库,这些库可以让许多程序员将关注点从创建新代码转移到组合现有的组件方面上来。最终结果就是它们被看作是基于C语言的“生产力语言”(productivity language)。如果想快速创建软件,而它几乎等同于去组合现有的组件(很多软件都属于此类),那么与C++语言相比,Java和C#都是不错的选择。

但C++不是生产力语言,它是一种系统编程语言。它旨在媲美C语言在以下几个方面的能力:硬件通信(如驱动程序和嵌入式系统方面),在不经任何调整的情况下可以直接处理基于C语言的库和数据结构(如遗留系统方面),用尽运行硬件上的所有性能。这里不是想嘲讽Java和C#语言底层虚拟机的关键性能组件都是使用 C++编写的,高性能虚拟机的实现就应该是系统语言干的事,不适合生产力语言。

D语言的目标是想在系统编程领域成为C++的继任者。像Java和C#语言一样,D语言也想要避免C++的复杂性。为此,D语言使用一些相同的技术,其中包括加入垃圾回收功能,摒弃手动内存管理 ;采用单继承和多接口,舍弃多继承。但是,D语言走的又是一条属于自已的路。

先是从标识出C++的功能性漏洞并修补它们开始。当前的C++未提供对Unicode的支持,而其后继版本(C++0x)也只提供了有限的支持。D语言从一开始就支持Unicode。当前的C++和C++0x都不支持模块(module)、契约编程(contract programming)、单元测试(unit testing)或“安全”(safe)子集(其中不可能出现内存错误)。D语言提供了上述所有功能,但未对生成高质量本地代码的能力产生影响。

针对C++强大与复杂兼有的特点,D语言瞄准的目标是:在保持功能强大的同时降低复杂性。C++中的模板元编程人员已证明,编译时计算是一项很重要的技术,但必须要先克服句法的困难才能将它付诸实践。D语言提供了类似的功能,但没有词法方面的烦恼。在当前的C++里,即使知道如何编写函数,你也不一定了解如何才能编写出与之对应的能在编译期间进行计算的C++函数。在D语言里,如果知道如何使用编写函数,你就能准确地知道如何编写其编译时版本,因为两种情形下的代码是一样的。

最有意思的地方是,在基于线程的并发性方面,D语言与其由C++派生出的兄弟语言之间使用的方法是截然不同的。D语言认识到对共享数据不正确的同步访问(数据竞争)就是一个陷阱—容易陷进去且很难爬出来。因此,它从一开始就约定:默认情况下,数据不会被跨线程共享。正如D语言的设计者指出的那样,在现代硬件深度缓存层次的环境里,内存并不是真正跨内核或处理器共享的。既然这样,那为什么还要默认给开发者提供的一种抽象呢?这种抽象不仅仅是一种错觉那么简单,它是一种错误的观念—众所周知,是它滋生了难以调试的错误。

所有这些内容让D语言在C语言的传统设计空间里特别引人注意,这一点已足以成为你阅读这本书的理由。而本书的作者是Andrei Alexandrescu,阅读理由变得愈加充分。作为D语言的共同设计者以及绝大部分D语言库的实现者,没人能比Andrei更了解D语言。他能对D编程语言进行描述,这是很自然的事,他也能解释D语言为什么是这个样子。有些特性出于某种原因存在于D语言里,而有些应该有的也正缺失的特性出于某种原因却未包含在D语言里。要阐明其中的原因,Andrei是不可替代的人选。

这种解释独特而富有魅力。其中有些内容似乎有点跑题(但事实上它们只是通往终点的一个中间站),Andrei对此作了保证:“我知道你在反问自己:编译时计算真的有必要吗?很有必要!请容我慢慢道来。”针对连接器诊断不够直观的根本性问题,Andrei说到“如果你忘记了--main,也不用着急。连接器会使用其本地语言—编码后的克林贡语 ,流畅、详尽地 提醒你。”即使是对其他出版物的引用,Alexandrescu也都有提及。他不是简单地像“Wadler的著作Proofs are programs”这个样子进行提及,实际提及的样式非常详实,如“Wadler的迷人著作Proofs are programs”;关于Friedl的著作Mastering regular expressions不是简单推荐,而是“热情推荐”。

一本关于编程语言的书自然满篇都会带有样例代码,而这些样例代码同时也说明Andrei是一个注重实践的作者。这里有一个他编写的搜索函数原型:

bool find(int[] haystack, int needle);

本书描述的是一门很有意思的编程语言,是由一位经验丰富的作者编写而成的。我保证你会发现这本书值得一读。