警惕“编译器人”和“函数式程序员”

多年以来,自从到 Coverity 工作,一直到 Shape Security,微软,Intel,直至跟阿里面试,我都深刻的体会到,做过些编译器工作的人,似乎很容易产生一种牛逼轰轰,高人一等的心理,以至于在与人合作中出现各种问题。由于他们往往存在偏执心理和理想主义,所以在恶化人际关系的同时,也可能设计出非常不合理的软件构架,浪费大量的人力物力。

我曾经提到的 DSL 例子,就是这样的两个人。都自称做过编译器,所以成天在我面前高谈阔论,甚至在最基础的概念上班门弄斧,做出一副可以“教育”我的姿态。而其实只有其中一人做过 parser,根本还不算是真正的编译器工作,就显示出高深莫测的姿态。另外一个完全就是外行,只是知道一些吓人的术语,成天挂在嘴边。每次他开口,我都发现这个人并不知道他自己在说什么。

我是被他们作为专家慕名请来这个公司的,来了之后却发现他们唯一想做的事情,是在我面前显示他们才是“专家”。他们也问过我问题,可是我发现他们其实并不想知道答案,因为我说话的时候他们并没有在听。他们只想别人觉得他们聪明。

更糟的事情是,这其中一人还是 Haskell 语言的忠实粉丝,他总是有这样的雄心壮志,要用“纯函数式编程”改写全公司的代码……

遇到这样的人是非常闹心的,到了什么程度?他们经常雄心勃勃用一种新的语言(Scala,Go……)试图改写全公司的代码,一个月之后开始唾骂这语言,两个月之后他们的项目不了了之,代码也不知道哪里去了。然后换一种语言,如此反复…… 因为烦于他们在我面前高谈阔论,我干脆换了一个部门,不再做跟语言和编译器相关的事情。

之前看工作的时候,有些美国公司在招人的时候明确表示,对简历里提到崇尚“函数式编程”或者做过“编译器”的人有戒备心理,甚至表示“我们不招编译器专业的人”。以至于我也被刷下来,因为我在 Coverity 做过编译器相关工作。编译器专业的人本来可以做普通的程序员工作,为什么有公司如此明确不要他们呢?我现在明白为什么了,因为他们可能是性格非常差的团队合作者,无法平等而尊重的对待其他人,总是一副高高在上,拯救世界的姿态。

现在经历了所有这些之后,我可以很明确的表态,我其实看不起编译器这个领域,而且我本来就不属于这个领域。

人们容易混淆编程语言(PL)和编译器两个领域,而其实 PL 和编译器是很不一样的。真懂 PL 的人也能比较轻松地做编译器,而做编译器的却不一定懂 PL。为什么呢?因为做编译器一般是专注于“实现”别人已经设计好的语言,比如 C,C++。他们必须按照别人写好的语言规范(specification)来写编译器,所以在语言方面并没有发挥的空间,没有机会去理解语言设计的各方面。

由于这个原因,做编译器的人往往用井底之蛙的眼光来看待语言,总以为他们写过编译器的语言(比如 C++)就是一切。一个语言为什么那样设计?不知道。它还可以如何改进?不知道。它就是那个样子!

实际上做编译器是如此无聊的工作,他们大部分时候只是把别人设计的语言,翻译成另外一些人设计的硬件指令。所以编译器领域处于编程语言(PL)和计算机体系构架(computer architecture)两个领域的夹缝中。上面的语言不能改,下面的指令也不能改。

编译器领域几十年来翻来覆去都是那几个编程模式和技巧,玩来玩去也真够无聊的。很多程序员都懂得避免“低水平重复”,可是很多程序员由于没有系统学习过编译器,误以为做编译器是更高级有趣的工作,而其实编译器领域是更加容易出现低水平重复的地方,因为创造的空间非常有限。

同样的优化技巧,在 A 公司拿来做 A 语言的编译器,到了 B 公司拿来做 B 语言的编译器…… 大同小异,如此反复。运气好点,你可能遇到 C,C++,Java。运气不好,你可能遇到 JavaScript,PHP,Go 之类的怪胎,甚至某种 DSL。但公司有要求,无论语言设计如何垃圾,无论硬件指令设计如何繁琐,你编译出来的指令必须能正确运行所有人用这个语言写出来的代码。你说这活是不是很苦逼?

然而编译器领域的人往往夸大自己在整个 IT 领域里的地位,做过编译器的人很多认为自己懂了编程语言的一切,而其实他们只是一知半解。你从我之前怼 Chris Lattner 的一些文章(链接1链接2)就可以看出来。虽然是编译器领域声名显赫的人物,却对语言有如此肤浅的理解,甚至在设计 Swift 语言的早期犯下我一眼就看出来的低级错误,改了一次居然还没改对。

编译器领域最重要的教材,龙书和虎书,在我看来也有很多一知半解,作者自己都没搞懂的内容,而且花了大量篇幅只是在写 parser 这种非核心的话题。龙书很难啃,为什么呢,因为作者自己都不怎么懂。虎书号称改进了龙书,结果还是很难啃,感觉只是换了一个封面而已。

我曾经跟虎书作者 Andrew Appel 的一个门徒合作过,她当时是 IU 的助理教授,让我写各种扯淡而毫无意义的论文,而且对人非常的 push 和虚伪。那是我在 IU 度过的最难受的一个学期,这使我对“编译器人”的偏见又加深一层。

顶级人物如此,其它声称做过编译器的人也可想而知了。大部分自称做过编译器的人,恐怕连最基本的的编译器都没法从头写出来。利用 LLVM 已有的框架小改一下,就号称自己做过编译器了。许多编译器人士死啃书本,肤浅地记忆各种术语(比如 SSA),死记硬背具体实现细节,无法灵活变通。

所以我常说,编译器是计算机界死知识最多,教条主义最严重的领域之一。经常是某个厉害点的人提出一个做法,起个名字,其他人就照着做,死记硬背,而且把这个名字叫得特别响亮。你要是一时想不起这名字是什么意思,立马被认为是法国人不知道拿破仑,中国人不知道毛泽东。

这就是为什么虽然有多次编译器的工作机会,包括 Apple 的 LLVM 部门,我最后都没去。进入 Intel 的时候,本来编译器部门也为我敞开大门,可是再三考虑之后还是选择了其它方向。因为我很清楚的记得,每一次做编译器相关工作都是非常压抑的,需要面对一些自以为是的人,而且内容真的是重复,无聊和枯燥。

我唯一敬佩的编译器专家是 Kent Dybvig,但我也不想跟他一起做编译器。最近很多公司找我去做“AI 编译器”,我全都拒绝了。

函数式语言爱好者,则是另外一种奇葩。对于这个我也写过文章,这里就不赘述了。

所以这两种人,在面试的时候一定要深刻了解他们的性格,态度和做事方式。否则牛逼轰轰的“编译器人”或者“函数式程序员”进了任何公司,都很可能对团队成为一种灾难。

我写这篇文章是为了广大 IT 公司,也是为了鼓励其它程序员。我希望他们不要被编译器的“难度”迷惑了,不要被自称写过编译器的程序员吓唬。你们做的并不是更低级,更无聊的工作。正好相反,真正可以发挥创造力的空间并不在底层的编译器一类的东西,而在更接近现实和应用的地方。

码中人 微信公众号

关注微信公众号

码中人 微信公众号