相信我的看法不是小众,很多人也有一样的,如果正确或局部正确说明我是后知者。
最近学习了一些处理器架构和自下而上的操作系统原理(大多数教材都是这样的),对编程语言有了一些新认识。
我一度从语言本身厌恶C,认为它既简陋又繁复:简陋在goto、数据类型等高级语言本应进一步提升的地方,繁复集中在“面向内存”如无穷且诡异的指针、函数定义和调用方式。。。
一种自上而下探讨操作系统的代表性观点是把操作系统与实现它的编程语言结合在一起,比如关于微内核的对话:
说实话我很久没有关心操作系统了,因为通常所谓的“操作系统”在我心里不过是一个 C 语言的运行时系统(run-time system),就像 JVM 是 Java 的运行时系统一样。由于 C 语言的设计缺陷,这些系统引入了各种无需有的概念(进程,线程,虚拟内存……),以及它们带来的复杂性和开销。
王垠认为合理的操作系统设计也是高度基于编程语言特征的,参考[1]。
然而硬件的知识和事实告诉我们,进程、线程、虚拟内存不是针对编程语言而是基于硬件底层的特征提出并发展的。批评将指针引入高级语言的CAR Hoare恰好就是这些概念的发展者(见参考[2]),Hoare本人也算是编程语言而且是极客式语言的发明爱好者,在他和同时代人的一些设计中这些内容作为类似数据结构或语言结构本身进行模拟。
随着处理器的出现和发展,计算机结构渐渐被处理器架构所集中代表,英特尔x86和摩托罗拉68000是目前仍然主要的学习参考和技术基础。在硬件层面,中断(interrupt)、并行处理所带来的进程调度都是切实存在的,异常处理也有硬件上的直接体现,其中进程和内存问题与外接和边缘设备(peripheral devices)密切相关,实际上多核处理器已经形成了网络结构,不同节点间通信必然产生复杂的数据和对相关数据结构模型的需要。因此,从编程语言表面出发认为 这种系统里面的程序间通信不使用无结构的字符串,而是使用带有类型和结构的数据。
可以作为更合理的设计忽略了硬件底层本身特征,是无法实现的。
学了这些东西之后之前觉得C诡异的地方都说得通了,感觉也能看懂很多原来看不懂的C代码了。
看上去神奇的Lisp machine其实也基于从硬件底层出发的设计,可能某些Lisp爱好者刻意隐瞒或者不清楚的一个事情是,Lisp的特征并不抽象,Lisp源于List Processing,Lisp的CAR和CDR是IBM 704的宏(Macro)[3] Lisp类语言的某些“超常”特性恰恰是与硬件底层的对接导致的,而那个时代标准化的指令集体系、国际通用的CPU架构都不存在,那是一个设计和制造计算机可以和今天嵌入式、FPGA一样灵活自由的时代。
基于以上谈C,一个无可否认的事实是,C的设计背景和表面特征都是与汇编-硬件底层高度对接。而它的好与坏也应该围绕这一点展开。Oberon的设计者Niklaus Wirth代表作《程序=算法+数据结构》前言就指出:A programming language represents an abstract computer capable of understanding the terms used in this language.
编程语言是抽象计算机的代表,而如何实现编程语言呢?当然是最终落到与硬件打交道。Python能不能整出一个直接架在处理器上的编译器?也许能,但无论如何duck type在汇编语言层面是极难/不可能做到的。当我知道Python的类就是内存中一块空间的时候惊了一下——太简陋了吧「不好意思冒犯py粉了」。
C语言和它的拓展比如C++/Objective C被人们经常提及的特征就是面向底层,因此它有自己特别适合的领域:直接调用硬件、对内存要求及其严苛、稳定性极高一旦出问题放在其他编程语言也够呛的软件开发。实时系统、一些嵌入式(现在的宇宙飞船的计算机内存仍然只有64k)是首选。然而其他领域的东西就应该找其他语言了。
所以我的观点非常平常,现在看来对C没有什么意见,反而真正厌恶是对C不正确的态度:把C族语言当作“最好”的编程语言,一切唯C试论。
既然专业叫“计算机科学”,触及范围应该全面,现在的信息是,计算机结构/处理器架构层面实际上有很多地层次到高层次共通的原理而且值得深入研究。计算原理/计算机原理的一些东西不能完全被编程语言代表,语言终究是有限的符号,我特别喜欢王垠的一个看法“(大意)人脑的计算过程类似电路,输出的语言类似toString”[4]「我不懂电路,但我非常认同“符号主义”本质上不合理的观点」
基于以上,编程永远是复杂复杂再复杂,大家都强调软硬件结合、代码一定要考虑硬件优化,但有些东西倒是基于人本身多于硬件底层比如客户端的东西(网页、交互设计。。。),真正做到用户体验和硬件性能珠联璧和应该是CS永恒的主题吧。
ps
1 操作系统的臃肿很大程度与程序和设备接口的复杂性有关,同时可能夹了开发者的私货(保密、反盗版。。。)
2 通用开发框架(设备通讯、物联网等)让软件开发更通用但也无形中增加了很多成本,C本身的语言特征不适合处理各种IEEE标准,应该有先用更高级语言/专用库开发然后用C对接的方法?
参考
[1] 一种新的操作系统设计
[2] Structured concurrent programming with operating systems applications
[3] https://en.wikipedia.org/wiki/CAR_and_CDR 这里特意加入了一个反对观点,但Lisp的设计者确实是基于704的汇编指令设计的Lisp
[4] "人腦其實根本就不是用人類語言在思考。人腦的思維方式更像是一種程序語言,一種電路,而不是人類語言。只有需要跟另一個人交流的時候,人腦才會把內部的數據結構轉換成人類語言,就像 Java 的 toString ()方法一樣。"http://www.rocidea.com/one?id=33719