编程珠玑番外篇-8.Smalltalk 中的珠玑

Nov 30, 2008

Comments

如果我们能够重回1980年, 回望整个计算机编程语言领域, 特别是工业界编程, 打死也不会想到日后 Java 这种无名小卒, 以及 C++ 这个又面向对象又支持过程的双面间谍能够红得发紫. 当年最流行的语言, 当属 FORTRAN, C 和 Smalltalk. 前两个我们按住不表, 单说这个 Smalltalk. 我们现在的教科书基本都不介绍 Smalltalk, 或者就用一句: Smalltalk 是第一个纯面向对象的语言 概括过去. 其实 Smalltalk 中有很多的好的思想, 一直在今天都发挥着魔力. 

施乐当年的图形界面(来源: harding.edu)

为提起大家兴趣, 我先说血统和设计等八卦. Smalltalk 的血统是算得上高贵的, 来自当年超级牛逼的 施乐 PARC 实验室. 施乐的 PARC 干过很多事情, 比较著名的一个故事是说乔布斯同学去参观, 看见那边科学家已经做出了 GUI (图形界面程序), 于是偷偷的回家搞 Macintosh, 搞好之后在1984年发布, 卖得大大的好, 赚得盆满钵盈. 西雅图当时有个大学没毕业做软件的小伙子, 看见乔老师赚了大钱, 想想觉得自己的人生挺没意思的, 只是和 IBM 做订购 DOS 的生意, 于是起了自立为王的念头; 加上看到乔老师的苹果机一个窗口一个窗口的很好玩, 于是一激动就自己搞了一个 Windows. (这个作软件的小伙子就是比尔盖茨啦). 这小伙子很牛, 把乔老师的苹果机逼到了角落里. 乔老师是最不能咽下恶气的人, 于是连在 Stanford 演讲了时候还不忘提一下微软抄苹果. 法律上就更不要说了, 两家公司之间旷日持久的 GUI 专利权官司从1988年打到1994年. 两家公司都一步不让. 最后施乐火了, 跳出来大喊一声: 靠, GUI 乃是我发明的. 于是把苹果给告了. 所谓螳螂捕蝉, 黄雀在后, 苹果被施乐这么一搞, 自己抄别人的老底就被挖出来了, 告微软就显得特别勉强, 所以官司最后也没赢, 以苹果无理取闹失败为结果.

施乐不光用 GUI 引领了我们现在计算机图形界面, 还发明了以太网, 鼠标, 所见即所得的编辑器等. 要不是这几样东西, 现在的计算机说不定是另一个样子呢. 言归正传, 前有施乐 PARC 出品了这么多伟大产品, 后加上 Alan Kay 这种牛人主导设计, Smalltalk 的血统之好, 和出自 AT&T Bell 实验室的 C 是有一拼的. C 还是两个人无聊敲打出来的, Smalltalk 是正儿八经作为一项研究弄出来的产品.  

事实上 Smalltalk 的确也是划时代的产品. 我就说我知道的两个部分. 

第一是现代程序员耳熟能详的 MVC 结构以及整个 Design Pattern 的思想. MVC 出现在 Smalltalk 中并不是偶然的. 当年施乐开发 Smalltalk 主要是用来做图形界面编程的, 而图形界面的编程首先就是从施乐发明图形界面开始的. 试想一个程序员成天写命令行程序, 肯定是不会太在意 MVC 的分离. UNIX 世界中并没有MVC的对应物, 因为压根不需要. 而图形界面程序的复杂度比其他程序要高太多了, 因此自然的就产生了 MVC 这样解开功能模块耦合的自然的设计. MVC 的重要程度和流行程度可以从两个小事情看出来. 第一是著名的 GoF 书, 翻开第一章第二节就开始讲 MVC, 用 MVC 作为整本书的纲领章节, 可见其重要程度. 第二是众多的 Java 框架, 比如Struts, JSF, 里面的对象就很直白的叫做 XXModel 或者 XXViewer. 这些传统都是从 Smalltalk 开始的, MVC 的影响一直到今天还到处都是. Smalltalk 不光催生了 MVC, 也催生了 Design Pattern. 细心阅读 GoF 的 DP 书我们就会发现, 里面所有的 Pattern 大多是在设计一个所见即所得的编辑器的背景下提出来的. 而上面我们已经说了, 施乐是第一家搞这个玩意的. 如果我们追溯 Smalltalk 早期很多的论文, 很明显可以看出, 虽然没有用 Design Pattern 这个词, 开发的时候要遵循一定的”对象结构”的思想是随处可见的. 

第二是我认为非常重要的: 运行时类型信息支持, 或者叫反射. 简单的说, 就是一个对象在运行的时候能够知道自己的类型(类名称), 以及这个类有哪几个方法, 哪几个字段等等. 

关于反射的基本概念在脚本语言里面是屡见不鲜的了. 大家都知道, LISP 里面的 eval 后面可以加任何的字符串, 构造出一个运行时对象. 脚本语言实现反射也很简单: 本来就是解释执行的语言, 多一个 eval 等价于多调用一次解释器而已. 而编译型语言就麻烦了, 因为解释器已经在编译期用过了, 运行的时候解释器是不存在的. 这样, 就造成了编译型语言没有运行时信息这个本质困难. Smalltalk 用了一个巧妙的方法解决了这个问题, 也就是 Java 和 Python 等现代语言用的方法: 虚拟机. 能编译的代码被先编译, 需要解释的代码在运行时可以被虚拟机自带的解析器再解析. 除了加入一个小的解释器到虚拟机外, Smalltalk 更进一步, 把对象的元信息也抽象成一个对象, 这样运行时需要的一个对象的所有元信息都能在面向对象的标准框架下表达. 我们用类 Java 的语言来举例: 一个叫 a 的 Foo 对象, 包含一个 a.hello() 的方法, 这个方法既可以通过 a.hello() 来调用, 也可以通过 a.class 先得到 a 的类, 再通过 a.Class.findMethod(“hello”) 找到这个方法. 最后再通过 .invoke() 调用这个方法. 这样的流程在没有虚拟机的 C++ 里面是没法完成的. 

在1980年, 这个反射机制的划时代意义是怎么说都不为过的. 我以我熟悉的 JUnit 的进化史为例说明这个议题. 

现在做单元测试的框架, 一般都被称为 xUnit 家族. xUnit 家族最早的成员, 不是 JUnit, 而是 SUnit (Smalltalk Unit). SUnit 的历史比 Junit 悠久得多, 大约在1994年的时候, Kent Beck, 也就是 Junit 的作者之一, 写了 SUnit. 而后才有了 JUnit (1998). 所以, 在 SUnit 的网站上, 极其显摆的写着”一切单元测试框架之母” (The mother of all unit testing frameworks). 事实上这是大实话 — 所有单元测试框架里面的名词术语, 都从 Sunit 来的, 如 TestCase, Fixture 等等. 

既然 SUnit 和 Junit 是同一个作者, 而早在1996年, Java 就已经成为工业界炙手可热的语言, 为什么要等到两年之后, JUnit 才横空出世呢. 这里面的原因说简单也简单: 自动单元测试需要反射支持.  1998 年前的 Java 没有反射, 直到1998年 Java 1.2 发布, 反射才完整的被支持. 所以, 只有1998年之后, Java 才有办法做自动单元测试. 

我们回顾一下 Junit 的工作流程: 继承一个 TestCase, 加入很多以 test 开头的方法, 把自己的类加入 TestSuite 或者直接用 TestRunner, 让测试跑起来. Junit 能够自动覆盖所有 test 开头的方法, 输出红棒绿棒. 这地方的关键是自动覆盖. 假如每个测试都是靠程序员自己写 printf 比较, 那不叫自动. 假如每个 TestCase 里面的每个 test 开头的方法都要程序员自己写代码去调用, 那也不叫自动. 所谓的自动, 就是在机器和人之间形成一定的规约, 然后机器就去做繁琐的工作, 最小化人的工作(RoR就是很好的例子). 

注意到我们的需求是 “让 Junit 自动调用以 test 开头的方法”, 而不需要自己很笨的一个一个自己去调用这些方法. 这意味着 Java 语言必须支持一个机制, 让 JUnit 知道一个测试类的所有方法名称, 然后还能挑出 test 开头的方法, 一一去调用. 这不就是反射么! 事实也证明了这一点: 目前互联网上找到的最早的 Junit 的源代码, 1.0 版的核心就只用了一个 Java 的标准库: reflect. 相反, 不支持反射的语言, 就得告诉单元测试的框架我要运行哪些. 比如说 C++ 的单元测试框架 CppUnit, 就很不方便–必须告诉框架我要测哪几个函数, 就算他们以 test 开头也不行. 还有一个好玩的例子是 J2ME 的测试框架. J2ME 是 Java 小型版, 不支持 reflect, 因此, JUnit 平移不上去. 如果细看所有的这些移植 JUnit 的尝试, 很容易发现, 移植出去的版本作用到有反射机制的语言上, 使用起来就很方便, 就比较成功, 比如NUnit; 没反射机制的就比较麻烦, 用的人也相对少, 比如 CppUnit 和 J2MEUnit. 反正任何对于 JUnit 的移植, 都绕不开”反射” 这个机制. 有反射者昌, 无反射者弱. NUnit 这个移植版本, 还曾经被 Kent Beck 夸设计好, 其原因, 与 C# 语言比 Java 更加良好的 attribute 和 反射机制, 是息息相关的. 

此外, 现代框架中流行的 依赖注射 (Dependency injection), 反转控制 (Inversion of control), 都是基于反射的. 这也就是为啥用传统的不支持反射的语言很多年的人很少听过这些名词的原因. 

有兴趣的读者可以继续阅读 wikipedia 关于反射元编程 这两篇文章, 相信会得到更加多的启示. 

Smalltalk 的IDE 开发环境 (来源: arstechnica.com)

Smalltalk IDE (arstechnica.com )

除了以上两点, IDE 和库的思想. 我们今天用的标准名词, 如”方法”, “字段”, 都是来自于 Smalltalk 的. 这些也都是划时代的工作, 因为我不熟悉, 也不敢不懂装懂的展开介绍了.  

有时候回看历史, 特别是回看编程语言的设计和进化的历史, 会发现很多散在的晶亮的珠玑. 

(完)


转载请保留出处和作者信息

Nov 24, 2008

Comments

我自认为是一个很好说话的人, 很多朋友在我这里转文章就直接拷贝过去, 连图片都链我的, 每月我白为转载的文章付好几个G的流量, 我也睁一只眼闭一只眼的, 权当是客气送人的. 

在转载这个问题上, 最近转我文章的比例越来越多了, 甚至到了别人向我推荐我的文章的地步.  因此, 对各位拷贝粘帖的唠叨几句: 请各位觉得我文章写得好的想转载的朋友们读一下我右边的声明: 十八岁以上转载文章请保留作者和出处. 有不少90后小孩转我的文章不留出处, 光盗链我图片, 我懒得较真.  对于18岁以上的, 我是把您当成完全有民事行为能力的人来对待的, 所以我相信转的人都明白什么叫版权, CC协议上的保留作者信息是什么意思. 

其实转载技术文章是很伤害作者积极性的, DBANotes 就很反对转载.好在我的文章一般搜索都是第一条, Google 对我照顾, 把转载的都排在后面, 所以我也不怎么感觉积极性受到了伤害. 指不定哪天我的文章排不到第一反而被转载的文章排到第一了, 我就得思考思考是不是该让人随便转载了. 

没啥大事, 就是友情提醒各位一句: 我这里的技术文章都是公开的, 自称体系的. 所以不建议转载. 如果要转载, 我也没啥意见, 只请保留作者信息. (格式可用: 本文转载自 4G Spaces by You Xu, 原文链接: xxx.) 有些哥们在这个问题上喜欢打擦边球, 文章标题也不注明转载, 写到最后了附送给我一个很不起眼的链接. 与其如此, 您还不如不转载了. 

原谅我煞风景唠叨这几句.


编程珠玑番外篇-7.比代码大全好的两本书B

Nov 23, 2008

Comments

各位读者老大中有不少都是大学生, 相信不少都参加过形形色色的英语写作培训班. 如果当年您参加培训班的时候, 老师没有介绍一本叫做 <The Elements of Style> (TEoS) 的书, 建议您现在立即冲过去找他们退钱. 为啥呢, 因为这本书是讲解英语写作绕不开的经典圣经(即使这本书已经被说烂了, 批评也不少, 但还是经典). 假如培训机构或者老师上课没推荐到这本书, 这个培训机构要不是太牛逼了, 要不是水货. 而大家都知道, 水货和牛逼的比例总是 1:epsilon.  

作为Amazon 上 297 个5星的书, 书评我就不狗尾续貂了. Knuth 爷爷也是很喜欢这本书滴, 因此在 Stanford 开课的时候让学生人手一本 (我们系今年新生也强制人手一本). 这本书不光勾勒了英语的基本写作要素, 也刻画了一个时代: 从此, 任何需要”艺术和技艺”的领域, 都会时不时跳出一些牛人, 模仿这本书的题材和哲学, 用简洁的文笔勾勒出这个领域的基本要素. 以我熟悉的计算机领域为例, 就有 “The Elements of Programming Style”, “The Element of Programming Style with Perl”. “C Elements of Style”, “The Elements of Java Style”, “The Elements of UML Style” 等等书, 都是希望继承 TEoS 的衣钵, 勾勒出编程的一些风格要素. 今天我要说的比<代码大全>好的书的第二本, 就是叫做 的. 我以前在[计算机科学必读经典](http://blog.youxu.info/2008/04/09/classics-in-cs/)中, 也提到了这本书. 

这本书作者和上一本 Software Tools 一样, 属于一个家族哲学下的两本不同角度的书. 关于它的书评也很多, 我就不一一废话了. 只说几个体会较深的. 

第一是写程序和写作一样, 要写的清楚. 这本书翻开第一条就是 Write clearly – don’t be too clever. 看上去说的和没说一样, 其实实践起来乃是金科玉律. 我曾自己写过三层嵌套的 “? :” 表达式, 写的时候自己被自己的聪明都感动了, 回来改的时候自己被自己当时的聪明给打击了: 死活看不懂当时啥意思, 只好写一个 printf 在后面测输出. 假如当时多花几分钟写的清楚一点明白一点, 就犯不着回头修改的时候花半小时破译了. 现实中的情况没这么极端, 但是也比比皆是. 相信任何正常的程序员, 每天都要为了理解以前写的不大清楚了程序浪费不少时间 (反正我是记不住一年前写的代码的每个小细节). 因此, 写的时候写的清楚比什么都重要. 

在写得清楚上, Knuth 爷爷是榜样. 他提出的 Literate Programming 的思想虽然太学术, 使得实践的人不多, 但是的确使得程序更加好读. Knuth 爷爷把他的用C语言作为基本语言的 Literate Programming 系统叫做 CWEB. 大名鼎鼎的 TeX 就是 CWEB 写成. 如果对 Knuth 爷爷比较粉的粉丝们恰好要做图算法,  Stanford Graphbase 是一本非常好的书, 里面贴得全是程序, 但是因为 Knuth 爷爷用 CWEB 写成, 文档和程序浑然一体, 读起来丝毫不觉得思维在程序和自然语言间做切换. Java 下有名的 XDoclet 和 Javadoc, 事实上也是 Literate Programming 的一种体现. 据 Knuth 爷爷讲他写 CWEB 程序能笑出来, 这种境界不是一般人能有的. 而且 Knuth 爷爷在提出 Literate Programming 的时候, 就野心勃勃的说: 写文章也是写, 写程序也是写, 我们 Literature Programming 的口号就是: 没有蛀牙 程序员也能拿普利策. (“I’m hoping someday that the Pulitzer Prize committee will agree.” Prizes would be handed out for “best-written program”.)

又八卦走题了. 言归正传, 我的第二个深刻的体会是”让计算机干脏活”. 什么叫脏活呢? 让你不爽的活叫脏活. 比如 Debug, 比如无穷多的复制粘帖, 比如替换一个大小写, 数数几个单词, 做做单元测试等等. 用眼睛瞄肯定会死人. 我以前在 “高效能编程的七个好习惯”  这篇文章中也说了, 就不多废话了. 

当然, 现实的问题是, 理论是理论, 实践是实践. 事实上, 我们要不然就是不用或者想不起来用工具(理由是不习惯), 要不然就是成为工具的奴隶. 李笑来老师也观察到了第一点, 比如这篇. 为什么明明别人告诉我有高效率工具和习惯存在的情况下, 我们还不去用不去改, 或者如何不成为工具的奴隶这两个话题都太大了, 我也写不好, 就不废话了. 然而, 不管最后实践用还是不用, 读一些被别人实践检验过的经验之谈还是很有用的. 这也是我推荐这本书的原因. 不知道大家有没有发现, 潜意识中如果有个正确的小声音不时在原则上提醒自己, 实践的时候潜移默化的就会越做越好. 

最后依然附送两个八卦. 第一个是关于 TEoS 这本书的. 这本书列了很多的原则和规则, 都是具体的对某个词某个句型的建议, 因此英语写作的时候可以直接应用这些规则. 不过对着书查规则显然属于脏活的范围, 所以呢, 我们的”让计算机做脏活”的哲学就发挥作用了: 在 Linux 下有一个程序叫diction, 用他可以检查英语写作的文章符不符合 TEoS 的标准, 我以前也专门介绍过. diction 会挑出那些不符合 TEoS 的句子, 告诉你让你修改. Knuth 爷爷也说, 虽然这个程序很笨, 但是至少可以强迫你重新审视你的文章, 挑出弱智的错误. 其实 GNU/Linux 下帮助英文写作的工具很多, 虽然不完美, 也称得上完整了. 我以前的文章可供大家参考 . 和 diction 一起的另一个工具叫做 style, 可以做像长句分析, 被动语态分析, 平均单词和词汇量估计等统计, 以及语言学水平上的英语水平估计(等价于美国几年级学生水平的估计). 这些估计都是语言学家研究数年的标准指标. 大家都知道, GRE 作文是计算机批阅的, 虽然我们不知道算法, 但是可以想象, ETS 那么笨, 肯定是请语言学家帮忙设计的程序, 所以必然或多或少的用到很多标准的语言学指标. 所以呢, 你不用计算机程序分析分析自己的文章, 光听培训机构的一些老师忽悠, 怎么知道自己文章水平呐? 相比较一些培训机构的老师, 指不定 style 这个程序更像 ETS 的评价标准. 

第二个八卦是关于写清晰的程序的. 或许大家都听说过史上最牛逼的注释的故事. 虽然各人有个人认为的最牛注释, 我个人喜欢的叫做 /* You are not supposed to understand this. */ (我不指望你懂这是啥意思). 这句话其实本来不该这么出名的, 恰好是因为出现在开源的第六版UNIX中, 恰好写的人是 Dennis M. Ritchie, 恰好澳大利亚出了一个叫 Lion 的人把 UNIX 源代码扒出来搞了个源码解析, 又恰好当年这本源码解析几乎每个黑客都人手一本. 所以, 这个极其挑战其他黑客智力的注释就变得流行起来鸟. DMR 同学对此有技术上的详细解释,  不再废话. 就是友情含泪劝告读者: 您要是在你的程序里面搞这么一句然后又被你同事和老板看到鸟, 你就完蛋鸟. 世上只有一个牛逼的 DMR 敢这么写.  

PS: 想要看看The Elements of Style 书的内容的老大们, 可以猛点这个链接

想要看 The Elements of Programming Style 说了哪些的老大们, 可以猛点这个链接

-EOF-


编程珠玑番外篇-5.比代码大全好的两本书A

Nov 22, 2008

Comments

上次我说到”比代码大全好的书“, 第一本指的是 . 为了说这本书的优点, 得先说这本书的缺点. 

这么书基本上绝版了. 而且也没有中文版. Amazon 连旧书摊总共就不到50本. 可见这本书目前不是一本让广大程序员喜闻乐见的书. 其次, 这本书用的说明问题的语言叫做 Ratfor, 基本上是 FORTRAN 和 C 杂交的产物. 估计全世界用这个的程序员和现存的这本书的数量差不多多. 但是你要是认为这是一本古董书, 烂书或者非畅销书, 那你就错了.  因为是一本编程书籍, 生命周期本来就短, 因此单以现在的销量判断好坏, 并不科学. 江湖失传已久的如来神掌送给周星星的时候, 周星星也不以为然. 但最后威力无穷. 希望这篇书评, 能够让读者信服这是一本如来神掌的秘籍. 

这本书的作者是 Brian W. Kernighan 和 P. J. Plauger . 关于这两个作者出书质量好的废话我就不多说了(不知道没听说第一个的回家用C写一个Hello, world 并面壁). 先说这本书讲的什么吧. 

这本书主要两条线, 一条是怎样通过一个叫做 Ratfar 的语言, 一步一步构建 UNIX 系统下的 cat, wc, tr, sort, tar 等等这些工具; 另一条是怎样和低级繁琐且不顺手的 FORTRAN 语言做斗争, 克服语言的障碍, 写出功能和可读性俱佳的结构化程序. 第一条着重强调的是一个系统的功能分解(对UNIX哲学清楚的读者看一下目录就一目了然), 第二条实际上是叙述了一个一脉相承到”代码大全”的哲学: 如何构建”你的”编程语言, 而不是简单的使用”别人的”编程语言. 这一条, 道出了整个编程的真谛: 编程就是构建一个一个”自己的”小积木, 然后用自己的小积木搭建大系统. 

为了说明小积木的道理, 我们从编程语言说起. 我以前的文章也提到过, C 并没有一个可以传递一行消息出来的 Assert 机制. 因此有经验的程序员会自己构造一个 Assert. 同样的道理, Java 虽然很高级, 却没有一个很好的单元测试框架, 所以全世界 java 程序员都在用 JUnit. 这些实践, 表明了一个现成编程语言总有一些特性不完美之处, 工具和使用者之间还有着不小的距离, 因此显得”不顺手”. 如果这个例子不够说明问题的话, 不妨问自己: 为什么人不能像写伪代码一样写程序呢? 因为我们使用了编程语言, 而编程语言有很多肮脏的细节要我们去处理, 比如下标从0开始, 浮点数不好作为数组下标等等. 语言的细节需要处理这个问题, 从 Fortran 到 Python, 只有程度的改变, 并没有本质的改变. 况且, 通用编程语言之所以通用并且简单, 就是因为支持的功能比较基本, 可扩展性强. 因此, 基本功能都有, 高级功能缺少成了通用编程语言的最大特点. 不管编程语言多么”高级”, 总是没有自己的思维高级. 因此, 编程的第一步就是把语言改造成自己的语言. 即使强大到直接能 import antigravity 的 Python, 也有需要改造的地方(最好的例子就是 Python 3000 的推出).

小积木有了, 就要构建大系统了. 在这一点上, Software Tools 可以说是非常好的一本源代码导读. 自从 Lion 分析 Unix 源代码以来, 源码剖析成了程序员修炼的一个捷径. 可是现在程序的源代码树都很繁杂, 能真的拿出来分析的很少很少了. Bell 实验室的两位作者从实作 UNIX 系统下的工具出发, 挑选出经过实践检验的优秀代码来讲解. 这样来自一线的题材是极其宝贵的, 就算在最新的 Beautiful Code 中, 大多代码也只是教科书代码而已. 至于代码大全, 完全就是玩具代码. 而 Software Tools 有几千行代码的大程序, 也有几行代码的小程序; 有算法程序, 也有文件IO程序, 基本覆盖日常所有用例, 对于内功修炼大有裨益. 

除了道出”改造你的语言”的真谛之外, 这本书其他论点也可谓字字珠玑. 比如讲goto带给程序员的自由恰好是你不想要的自由, 因为这个自由会带来很多错误. (很多语言都有这种不想要的自由, 比如 C++, 到处都是). 比如说讲结构化编程不会自动带来清晰的程序, 因为机械的规则永远不能代替清晰的思考. 这个道理在面向对象/设计模式领域也一样. 比如本书还论证了为啥要详细设计, 因为设计和编码环节对于程序员讲是愉快的事情, 值得更多投入. 而 debug 和 测试环节是比较痛苦的事情, 所以要少投入. 还比如人比机器时间贵, 所以程序员要越懒, 越快完成编程越好. 除非程序太慢, 否则从总成本看, 机器多用点时间没事, 人用的时间要越少越好, 等等等等. 类似于这样的深刻揭示编程的哲学理念的句子俯拾皆是, 比起相同内容但是篇幅冗长的代码大全, 这本书适合随身携带, 随时阅读, 随时提高. 

老规矩, 结尾顺手说个八卦吧. 话说为了把 Ratfor 这个假想的语言翻译成当时最流行的两种语言, FORTRAN 和 PL/I, bwk 爷爷写了一个宏替换的工具, 能够把 Ratfor 替换成肮脏的 FORTRAN, 而他们写干净的 Ratfor. Dennis Ritchie 爷爷看到鸟, 很赞, 于是推广了一下这个宏替换工具, 起个诡异的名字叫做 m3 (macro for ap3). 然后 bwk 爷爷又看到了 dr 爷爷的工作, 回过来又和 dr 爷爷合作, 写出了金光闪闪的 m4. 如果你常常编译开源软件, 肯定会注意到一个叫做 configure 的生成 makefile 的程序. 这个 configure 的读入, 一般情况下是可配置的, 叫做 config.ac, 就是 m4 语言写的. 虽然因为版权问题, 现在 GNU m4 和两位爷爷没啥关系了, 但是基本的语法和用法都是一样的. 各位知道 K&R 的读者千万不要错过这个好用的工具(也是编程语言). 

这个工具其实我也只懂皮毛, 也不常用, 只是用来自动编号一些行, 做一些稍微复杂一点的不能用正则的文本替换. 不过我似乎在某个地方听一个高手说, Linux 命令行下文本处理三剑客乃是 sed/awk/m4, sed 和 awk 的强大早就见识了, 相必m4与他们各有千秋. 故而略介绍一下. 

另外, 本书也是 troff 排版的. 按照我的 troff 排版无烂书定理, 这本书也属一流好书.


听说那个有太祖题词的校门要拆了

Nov 21, 2008

Comments

中国有一个不怎么一流的大学, 在国民政府的首都. 到今年大约106年了. 本来是前朝的中央大学, 可是为了孝敬太祖皇帝, 愣是在校门上搞了几句天朝太祖的话: 团结紧张 严肃活泼. 乃是抗大当年的题词. 一所好好的大学, 非搞个党校和军校的校训, 乃是有”服从党的领导”的意味. 大学的牌子也是太祖题的, 字不怎么样, 却金光闪闪. 大学的后面是省政府, 前门是法院. 都是红顶子出入的地方.

据说该城市明真相的人民群众被一大撮守法的红顶子煽动, 觉得他们出入政府大院的车道被老百姓堵了, 于是代表全市人民合理反映路不够宽的问题. 政府领导通知耐心劝说有效后, 为群众所想, 急群众所急, 要在城市中心建一条主干道.  可是省政府和法院的地头动不了, 于是就想把该大学和其他两所大学一起给腰斩了. 太祖早有口谕: 我党如此多娇, 引无数大学知识分子竞折腰. 所以各位也不要惊讶. 只是时代不同鸟, 太祖不是镇山之宝鸟, 他的题词也能随便推土机拆掉鸟. 校门上几句抗大校训, 估计不久也要去见陪太祖一起见马克思了.

常常有人问, 中国为啥出不了一流大学呢? 中国怎么就没有诺贝尔奖呢? 你猜我怎么回答? 我说: 呵, 呵呵, 呵呵呵. 呵呵呵呵. 你见过猪上树么?

(你要是问我对这个很弱智的规划怎么看, 我说: 呵呵, 呵呵呵呵, 呵呵呵呵呵呵, 你见过聪明的猪么?)