ero 的故事 [1] = 绕出

km.zero 是以 zero 所提倡的那种编程方式的一个示例,可使用以下命令获取它:

$ wget https://github.com/liyanrui/zero/raw/master/example/ConTeXt/km.zero
km.zero 包含了许多 C 代码片段,还有一部分 Bash 代码,其他内容完全由 ConTeXt(一种 TeX 格式)标记文本构成。这些 C 代码片段按照我个人的行文习惯以一种较为容易理解的逻辑顺序嵌于 km.zero 文件之中,如何将它们提取出来交给 C 编译器呢?

从编译器/解释器的角度来看,zero 的行为是非常荒谬的。因为 zero 似乎将编译/解释器所喜欢的代码片段顺序完全的打乱了,像是将一根线弄的乱成一团。事实上并非如此,zero 在打乱代码片段顺序的同时,也为每份代码片段放置了一些标记。通过这些标记,可以随时将这些代码片段重新排列为编译器偏好的那种形式并保存为程序代码文件。

在继续下面的话题之前,需要安装 zero:

$ git clone https://github.com/liyanrui/zero.git
$ cd zero
$ ./configure
$ make
$ sudo make install
km.zero 文件中,有一份名为『agn_km.c』的代码片段:

@ agn_km.c # ^+

include

include

include

include "agn_km.h"

@
注: @ ... # 中的 ... 便是代码片段的名称。

可以将它想象为一根线的『线头』。若系统中已经安装了 zero,使用以下命令,可将这根线——km.zero 中所有这个代码片段相关联的代码片段抽取出来:

$ zero --mode=night --entrance="agn_km.c" --output=agn_km.c km.zero
抽取结果是可编译的 agn_km.c 文件。

zero 支持短命令选项,上述命令可简写为:

$ zero -m night -e "agn_km.c" -o agn_km.c km.zero
『-m night』是 zero 的缺省选项,可省略,因此上述命令可进一步简写为:

$ zero -e "agn_km.c" -o agn_km.c km.zero
km.zero 中不止一根线,其他几根线的线头分别是『ang_km.h』,『agn_points.h』以及『agn_points.c』,zero 可以将它们一并绕出:

$ zero -e "agn_points.h, agn_points.c, agn_km.h, agn_km.c" \
-o "agn_points.h, agn_points.c, agn_km.h, agn_km.c" km.zero
-e 与 -o 选项的值相同,这只是偶然,并非必然。前者是各个『线头』的名称,后者是绕出的各条『线』的名称,它们必须逐一对应,不能乱了次序。

其实,km.zero 还有一根线头『gen-km-src.sh』,通过它可以绕出一份 Bash 脚本:

$ zero -e gen-km-src.sh -o gen-km-src.sh km.zero
执行这份 Bash 脚本可从一组 .zero 文件中绕出一个 $k$ 均值聚类的测试程序的全部源码文件。

注:由于不便将全部源码文件都放出,所以在上述示例中绕出的源码文件或 Bash 脚本均不可用。

上文所用的『线头』与『线』的比喻,不是我创造的。在很久很久很久以前,Donald Knuth 将这个过程称为 tangle。可能是因为这个过程,类似于从一团混乱的线团中找到一根线的线头,缠在绕线器上,将它抽取出来。Knuth 所写的文学编程工具 WEB,用于从 WEB 文件中抽取可编译的 PASCAL 代码的工具就叫 tangle,『zero -m night』与之类似。

编程语言是形式化的,遵循严格的机器规则——图灵机,或遵循某种数学演算规则——Lambda 演算。zero 试图将自然语言与编程语言结合到一起,有人对此持否定态度。不过,他们否定的角度完全是错的。他们非常错误的将文式编程理解为让自然语言凌驾于编程语言之上,或者让编程语言更像自然语言。事实上,文式编程强调的是代码片段出现的顺序应该符合人类的阅读习惯,不是在强调谁比谁更好,更不是强调谁可以取代谁。

编程语言固然是形式化的,是精确的,是可推导的,而自然语言固然是含糊的,这有什么问题?阅读程序代码的人不也是在做各种形式的阅读笔记吗?在从程序代码中追寻函数的调用关系、类的继承关系以及模块的依赖关系的过程中,难道不需要将自己好不容易追寻到的线索以及与这些线索相关的知识记录下来吗?如果真的不需要作这样的记录,那么《莱昂氏 Unix 源代码分析》、《深入理解 Linux 内核》、《Linux 内核的设计与实现》之类的书籍一版又一版的出,意义何在?

不过,认为直接阅读代码就可以弄懂代码的人,在使用『zero -m night』从 zero 文件中绕出可编译的代码之后,可将 zero 文件删除……以此表示对 zero 的蔑视。

关键字:文式编程


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部