几年前,王垠写了一篇批判文式编程的文章『On literate programming』( http://yinwang0.wordpress.com/2011/05/18... ),之所以现在才拎出来驳一下,是因为以前没看到。他在 2014 年写的一篇文章『我和权威的故事』( http://www.yinwang.org/blog-cn/2014/01/0... ) 中还是坚持着原有的观点。
王垠认为,文式编程会导致程序的大图景(Big Picture)的丢失。他认为,程序像电路或汽车,存在很多相互连接的零部件,如果将这些零部件分开来讲,会割裂它们之间的联系。
王垠可能没看过《冰与火之歌》系列的小说,这部书塑造的也是一个很复杂的系统,存在很多相互联系的角色,但是作者却可以游刃有余的通过 POV 的方式将这个系统刻画了出来。
人类所设计的系统,无论它有多么复杂,都具备可分解性,否则这个系统就很难被人类理解。即使这种系统难以用文字很直白的描述出来,依然可以通过图形示意的方式辅助描述。如果汽车系统能用教科书的形式描述出来,那么它的具体设计及制造过程自然也就能用书的形式记录下来。
文式编程不会搞丢大图景,除非写程序的人本来也没啥大图景。
王垠认为,文式编程工具不具备解析程序代码的能力,只是将代码分割为一段一段的文本,会导致变量作用域混乱,引入潜在的 bug。
还是以《冰与火之歌》为例,它那么长篇的书,也没有出现哪个角色在这一章里是死的而在另一章里还在说话的事。写程序这事,归根结底也是得看匠心的。
将程序分割为文本也不一定就必然会出现变量作用域混乱。例如,用 C 写程序,一个 C 函数可能包含了上百行代码,但是这并不意味着你在编写这个函数的过程中就用文式编程。先将这个函数实现出来,验证无误后再将它拆分为更容易理解的代码段,再配上文字说明或图形示意。如果你觉得这个函数的功能很简单,没必要解释,那就不用解释。
王垠认为,人类不是至高无上的,人类的语言是不精确的,程序语言却是在很多方面高于人类语言的,它不应该受到人类语言里的糟粕的影响……
即使 Knuth 本人,作为文式编程的倡导者,也没有说是要用人类的语言取代或影响编程语言,他只是说程序代码要按照人类的逻辑而不是按照编译器的逻辑来安排。这没啥好批判的,也许只有 PL 或编译器专家之类的职业病患才喜欢按照编译器的逻辑来理解程序代码。文式编程里,人类的语言虽然不精确,但是它可以很好的诠释代码片段的含义,而更精确的理解,可从文字附近的代码片段中获得。
如果直接丢给你一段代码,让你分析一下它实现的是什么功能,这种事其实就是逆向工程。想想人类破译甲骨文的工作方式及其难度吧。如果代码中有寥寥几句注释,那么逆向难度会被显著降低。这个星球上,最好的程序员,难道从不在代码中写注释么?代码的注释,用的难道不是不精确的人类语言么?
王垠还认为,程序代码不应该迎合个别人的认知习惯,它应该符合它的建模的概念本质(The nature of the concept it models)。不觉得这『个别人的认知习惯』与『建模的概念本质』有什么冲突的地方。所有写程序的人,都是『个别人』,他们所写的代码也必然是按照他的认知习惯所创造出来的『建模的概念本质』而编写出来的,而那些经典的建模的概念本质,往往也是通过论文的形式流传于世的。
王垠认为,Knuth 的书让他看起来很费劲,不如直接用 IDE 看代码更有效率。
对于文式编程,要解决这个问题很简单,产生带超级链接的电子文档就可以了。之前说过,我在寒假时用自己写的文式编程工具写了个 k 均值聚类程序,它的文档中的代码片段就是有超级链接的(详见 https://segmentfault.com/a/1190000004669... ),我没觉得代码浏览有什么不便之处。
无意于推销文式编程,仅觉得这只是个编程习惯的问题而已。不习惯,就不要用了,要黑,也得有理有据才行。
万万没想到,有生之年,我也能黑一次垠神 :)