C++:民主的产物

民主政体:C++的设计哲学

摘自《C++语言的设计与演化》

1) 这就意味着语言的设计已经脱离了“纯粹的”和更抽象的学科,例如数学与哲学。为了更好地为了它的用户服务,一种通用程序设计语言必须是折衷主义,需要考虑到很多实践性和社会性的因素。

2) 特别地,每种语言的设计都是为了解决一个特定问题集合的为题,在某个特定时期,依据某个特定人群对问题的理解。由此产生了初始的设计。而后它逐渐成长,去满足新的要求,反映对问题以及对解决他们工具和技术的新理解。

3) 我矢志不渝的信念是:所有成功的语言都是逐渐成长起来的,而不是仅根据某个第一原则设计出来的。原则是第一个设计的基础,也指导着语言的进一步演化,但是原则本身也是同样是发展的。

4) 尊重人群而不尊重人群中的个体实际上就是什么也不尊重。C++的许多设计决策根源于我对强迫人按某种特定方式行事的做法极度厌恶。历史上一些最坏的灾难起因就是理想主义者们试图强迫人们“做某些对他们最好的事情”。这种理想主义不仅导致了对无辜者的伤害,也迷惑和腐化了施展权利的理想主义者的自身。我还发现,对于其教义或者理论出现不寻常的冲突的经验和实验,理想主义者往往有忽略它们的倾向。在理想出现问题的地方,甚至空谈家也要赞成的时候,我宁愿提供一些支持,给程序员以选择的权利。

5) 经常遇到这种情况,如果我试图去取缔一个我个人不喜欢的语言特征时,我总抑制住自己这样做的欲望,因为我不认为自己有权把个人的观点强加给别人。我知道通过强力地推行逻辑,毫无同情心地谴责“思想中坏的,过时的,混乱的习惯”,可能在相对短的时间里有更多的建树。但是,人的代价总是最高的。不同的人们确实会按不同的方式思考,喜欢按不同的方式做事情,对于这些情况的高度容忍和接受是我最愿意的事情。

6) 我设计C++只是为了解决一个问题,而不是想证明一种观点,而它的成长有能够服务于它的使用者。

7) 尤其是我绝不想通过一种很有局限性的程序设计语言定义去推广某种唯一的设计理念。人的思维方式是如此的丰富多彩,企图推行一种唯一理念总是弊大于利的。这样,C++被有意设计成支持各种各样的风格,而不是强调“一条真理之路”。

8) 我的牢固信念是,语言设计并不是纯粹的思维训练,而是一种在需要,想法,技术,和约束条件之间取得平衡的非常实际的修炼。一个好语言不是设计出来的,而是成长起来的。这种修炼与工程,社会学和哲学的关系比数学的关系更密切些。

9) 对语言设计者总存在极大的诱惑,引诱他去提供某些特征或者服务,而在这些地方,用户原来需要采用迂回的方式去解决问题。而且,要求添加某些要求被拒绝而产生的尖叫声,远比对“又增加了另一个无用特征”的抱怨声响亮得多。这种争论的最坏变形就是对正交性的崇拜。许多人认为,如果在语言中增加了一个特征可以使他更具有正交性,那么这就是接纳这个特性的充分证据。我赞成正交性在原则上是一个好东西,但也注意到总要为它付出代价。

10) 在正交性的所有好的含义之外,在手册和指导材料中定义各种特征的组合通常也需要做许多额外工作。

11) 对于C++,我总是考虑对那些不使用组合方式的人,正交性将在运行时间和空间付出什么样的代价。如果这种代价无法在原则上能成零,我就很不情愿接受这个特征——即使它是正交的。也就是说,正交性应该作为第二位的原则——放在对于有用性和效率的最基本考虑之后。

12) 从根本上说,静态类型检查的概念被看成是为了程序提供一种尽可能强的保证,而不仅仅被作为一种取得运行效率的手段。

13) 很自然,静态类型检查对于调试很有帮助。但是把基础放在静态类型检查上的最根本原因,则是我那时就确信(现在依然如此),一个由通过了静态检查的部件组合而成的程序与一个基于弱类型检查或动态类型检查的接口的程序比起来,更可能是忠实地表达了一种经过深思熟虑的设计。当然,也应该记住,并不是对每个接口都能彻底地做静态类型检查,静态类型检查也绝不意味着不会有错误。

14) 设计一个库比增加一个语言特征更好,这种情况是经常出现的。

15) 因为没有任何语言能支持人们所需要的全部特征,又因为即使语言的扩充被接受了,也还是需要时间去实现和部署,人们应该总把库作为第一选择。设计一个库,实际上经常能成为追求新机制的狂热的一种最具有建设性的发泄方式。只有在迈向库的道路真正走不通的情况下,才应该踏上语言的扩充之路。

16) C++最有实力的地方并不是它的某个独到之处特别伟大,而在于它在事物的大范围变化中表现都很不错。与此类似,从根本上说,其发展也不是来自某个孤立的进步,而是来自在不同领域的大量的各种各样的进步。

17) 所有的语言都要死亡,或者为迎接新的挑战而改变。一个有着极大的而又活跃的用户社团的语言将总是去改变而不是死亡。这就是发生在C语言上的事情,并因此产生了C++。到某一天,这种情况也可能出现在C++身上。

18) C++并不完美,它也没有想成为完美的东西,任何其他通用语言都不可能。但无论如何C++已经足够好了,因此不会被另一个类似的语言所取代。只有某个根本上不同的语言才有可能提供显著而充分的优点,成为明显的更强者。

19) 仅仅作为一个更好的C++还不足以导致一个大转变,这就是为什么C++不能只是一个更好的C的原因:如果C++没有提供重要的新的写程序的方式,程序员就根本不值得从C方面转过来。这也是为什么Pascal和Modula-2无法成为C的替代性选择的原因,虽然学术界中很重要的一部分人多年来一直推动这些语言也不能成功,因为它们与C并没有重要差别,其优点不那么显著。

20) 还有,如果某个更好但又没有截然差别的东西出现,一个热爱着原有事物的多样化社会就会简单地吸收那些新的思想和特征。在C++的初始设计,以及它发展到当前这个语言的演化过程中,存在着许多这方面的例子。

21)C++长处,更多的在于它对许多问题都是很好的解决途径,而不在于它对某个特定问题是最好的解决途径。

C++的设计规则

规则与原理:

1)要成为真正有用的,人们乐于使用的东西,程序设计语言的设计就必须有一种全局观,用它来指导语言中各种特征的设计。对于C++,这种全局观有一组规则和约束构成。称它们为规则,是因为我认为原理这个词在真正的科学原理非常贫乏的领域显得过于自命不凡,而程序语言设计就是这样的一个领域。

2)此外术语“原理”也意味着:任何例外都是不可接受的。而我的有关C++设计的规则几乎可以保证都有例外的情况。实际上,如果一条规则与某个实际试验发生冲突,这个规则就应该靠面站。这样说,看起来似乎有些粗鲁,但是它不过是一条一般性原则的变形:理论必须与试验数据相吻合,否则就应被更好的理论取代。

C++的目标:

C++应该使认真的程序员能够觉得编程序变得更愉快了。C++是一种通用的程序设计语言,它应该是:

1)一种更好的C

2)支持数据抽象

3)支持面向对象的程序设计

 

一般性规则:

最一般和最重要的C++规则与语言的技术方面并没有太大的关系。这些规则几乎都是社会性的,其关注点是C++所服务的社团。C++语言的性质很大程度上出于我的选择,我认为它们应该服务于当前的这一代系统程序员,支持他们在当前的计算机系统上解决当前遇到的问题。最重要的是,当前这个词的意义和性质总是随着时间而变化,C++必须能够发展,以满足它的用户的需要;它的定义不应该是以成本不变的。

1) C++的发展必须由实际问题推动;

改变C++的正确推动力,是一些互相独立的程序员证明了这个语言对于表述它们的工作项目存在哪些不充分的地方。我更喜欢来自非研究性的项目,无论何时,只要可能,在努力发现问题和寻找解决办法时,我总设法与实际用户联系。我如饥似渴地阅读程序设计语言的文献,寻找对于这些问题的解答,也寻找各种可能有所帮助的技术。但我也发现,文献在考虑什么是真正问题方面是完全不可靠的,理论本身并不能为加入或者去掉一个特征提供充分的证据。

2) 不被牵扯到无益的对完美的追求之中;

任何程序设计语言都是不是完美的。由于问题和系统都在持续的变化之中,将来也不可能有完美的语言。用许多年工夫去修饰一个语言,以图去接近某种完美的概念,这样做只能是使程序员无法从那些年的进步中获益,也会使语言的设计者不能得到真实的反馈。没有适当的反馈,一个语言就会逐渐发展成为一种与时代不相关的东西。

重要改进的需求必须依靠反馈信息,并伴以对兼容性,转变过程和教育的认真考虑。随着语言的逐渐成熟,必须更多的倾向于使用基于工具,技术和库的替代性方式,而不是去改变语言本身。

3) C++必须现在就是有用的;

4) 每个特征必须存在一种合理的明显的实现方式;

当然,使用者总比写编译器的人多得多,所以如果出现需要在编译复杂性和使用复杂性之间的权衡问题,解决方案必定是偏向用户的。我在许多年做编译器维护的生涯中,已经真正理解了这个观点。

5) 总提供一种转变的通路;

要清除一种不安全,容易出错或者简单的有毛病的语言特征,最一般的策略就是首选提供一种更好的替代品,然后建议人们避免使用老的特征和技术,而到数年之后——如果要做的话 -再删除那个有问题的特征。这种策略可以有效的通过让编译器产生编译警告信息方式去支持。

6) C++是一门语言,而不是一个完整的系统;

7) 为每种应该支持的风格提供全面的支持;

简洁是最基本的东西,但是这个问题也应该针对将要使用C++项目的复杂性来考虑。与保持语言的定义比较简短相比,应该把用C++写出的系统的可维护性和运行时的性能做为更重要的问题。这实际上意味着要做一个相对规模较大的语言。

8) 不试图去强迫人做什么;

我也很清楚的意识到,并不是每个人都赞赏选择和变化。无论如何,那些偏爱带有较多限制环境的人可以在C++中始终如一的坚持使用某些规则,后者另去选择一种只给程序员提供很小的一组选择的语言。

设计支持规则:

1)支持健全的设计概念

不可能有一种语言能支持所有的风格,而如果一个语言只支持某种定义狭隘的设计哲学,它也将因为缺乏适应性而失败;

2)为程序的组织提供各种机制

3)直接说出你的意思

缩小这种(不同程序员的编写程序)语义鸿沟的最基本的方法是使得语言更具有说明性。C++语言提供的每种机制都与使某种东西更具说明性有关。然后是为了一致性检查,检测出愚蠢的错误或者改进所生成的代码而开发的一些附加结构。

4)所有特征都必须是能够负担的

5)允许一个有用的特性比防止各种错误的使用更重要

你可以在任何语言中写出很坏的程序。真正重要的问题是尽可能减少偶然将某些特征用错的机会。

当然,一个系统程序设计语言不应该禁止程序员有意识地去打破系统的限制,所以设计的努力应该更多地放在提供一些机制,帮助人写出好的程序方面,而不是禁止不可避免的坏程序方面。

6)支持从分别开发的部分出发进行软件的组合

语言的技术性规则:

1) 不隐式地违反静态类型系统;

只要有可能,总在编译时进行检查。只要有可能,那些在处理单独编译单位时只能提供信息而无法检查的东西,都有要在连接时进行检查。最后,这里还提供了运行时的类型信息和异常机制,以帮助程序员处理编译和连接都无法捕获到的错误条件。当然,在实践中,还是编译时的检查代价更低,也更值得信赖。

2) 为用户定义类型,提供与内部类型同样好的支持;

3) 局部化是个好事情

4) 避免对顺序的依赖性

5) 如果有疑问,就选择该特征的最容易说清楚的形式

6) 语法是重要的(常以某些我们不希望的方式起作用)

保证类型系统的一致性,一般而言,保证语言的语义清晰,定义良好是最基本的东西。语法是第二位的,而且看起来人们能够学会去喜爱任何语法形式。

7) 清除使用预处理程序的必要性

过去这些年,C++的最强和最弱的地方都在于它与C的兼容性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章