过去九年,我一直致力于推动软件开发工具的发展。此前,所谓“编程工具”只是文件的格式化浏览和编辑窗口,也会提供多种查找方式。对此,我曾深入提出,如何使编程工具能推理一组更改背后的意图,进而不再局限于“查找并替换”。
时过境迁,编程人员对程序合成(program synthesis)等概念已耳熟能详,甚至已上手了某种验证工具。以高级开发工具研发为基础,市场上推出了多种得到广泛使用的产品,甚至 Facebook 已经企业内部部署了自动程序修复。
尽管编程工具广为部署,但学术界对工具的研究遥遥领先。我们常常会看到,即便是发表于二十多年前的学术论文所提出的理念,经实验性验证可将一些任务的开发效率提高数倍。但这些理念仅局限于学术界。
本文将浅析开发人员对高级工具的期望,以及所发生的退步。下面给出的三款工具出现于过去 30 年中,尽管我对它们的个人评价很高,但经我实测,均已无法正常运行。
反射模型(Reflexion Model)
软件通常表示为组件。对于操作系统,组件就是文件系统、硬件接口和进程管理器等。如果一个项目需要实现更快地写入文件到磁盘,那么经验丰富的工程师能定位到确切的代码位置,而新手则面对一大堆的源文件会无从下手。
1995 年,就读于华盛顿大学的年轻研究生 Gail C. Murphy 提出了一种理解代码库的新方法,称为“反射模型”(reflexion model)。具体描述为:
首先,对各组件及相互间交互做出大体上的假设。
进而查看源代码,记录下对组件与源代码对应关系的认识。
之后通过运行工具,获得文件间的实际关联(例如,类的继承关系、对象图的调用关系等),并与前期假设做对比。
最后,基于实践认知,修正前期假设,不断充实对模型的认知,使认知模型逐渐逼近事实。
大约同时,微软的一个研究小组也在开展一项实验。该实验的目的是验证是否能改造 Excel 代码库,从中抽取出部分高层组件。这需要对代码库具有相当深入的理解,考虑到该小组与 Execl 开发团队完全没有交集,实现此事并非易事。研究小组中有人看了 Gail 关于“反射模型”的宣讲,深以为然。
他用一天的时间就建立了首个 Excel 反射模型,通过日渐熟悉代码而不断修正模型。在随后的四周时间中,他对代码的理解达到了先前预估需两年时间才能企及的程度。
时至今日,Gail 发布的 RMTool 已无法从因特网公开获取,其所基于的 AT&T C++分析工具 Ciao 同样也从因特网下线。尽管有人随后使用 Java 重写并实现为 JRMTool,但其仅能用于 Eclipse 的早期版本,完全不适用于当前的 API 了。JRMTool 采用 Java 1.4 编写,当前的 Java 发行版在语法上做了彻底更改。因此,我完全放弃了尝试获取代码并编译运行的想法。
时至 2021 年,软件工程依然无法超越 1995 年的水平。
WhyLine
时间又过了十年,卡内基梅隆大学人机接口(HCI)研究所的 Amy Ko 思考着另一个问题。调试过程就像是当侦探,为什么程序不在完成取数(fetch)后更新缓存?其中负数起了什么作用?为什么解答此类问题如此费劲?
上述想法促成 Amy 设计了一种称为 WhyLine 的工具。WhyLine 提供交互式调试界面,用户可提出“为什么某事会发生?”之类的问题。WhyLine 在图像编程工具 Alice 中实现了一个原型。Alice 是 CMU 实现的图形化编程工具,即便是儿童都可生成三维动画,令人印象深刻。
Amy 基于原型的成功,又历经数年努力,建立了针对 Java 语言实现该功能的技术。
他们开展的一项研究,要求 20 位程序员去修复存在于 ArgoUML 中的两个错误,这是一个 15 万行 Java 代码的程序。一半参试程序员使用 Java WhyLine。实验结果表明,相比未使用 WhyLine 的程序员,使用 WhyLine 程序员的成功率提高了四倍,工作速度提高了两倍。
我在几年前曾试图使用现代 Java 字节码平台去运行 JavaWhyLine,但是程序崩溃了。
MatchMaker
2008 年,我的导师 Armando Solar-Lezama 加入 MIT,一手恢复了程序合成(program synthesis)领域的研究。他过去主要关注小型系统中的复杂问题,包括优化物理仿真和位交错(bit-twiddling),目前正转向解决大型系统中的简单问题。
大多数的编程工作其实是在编写“胶水代码”,只需厘清如何组合使用大量的标准组件库。要明确如何使用复杂框架执行特定操作,可能需要花数周时间深入阅读文档。程序合成技术是否能在其中发挥作用?这正是来自哈萨克的天才 Kuat Yessenov 研究去解决的问题。
使用胶水代码的通常规则,是弄清楚需使用的具体类和方法。有时程序员能猜测得八九不离十。例如,Android 中使用 Container 类的addView
方法即可在屏幕上部署小组件。但更多情况下是不容易猜到的。例如,在编写一个能高亮显示语法的 Eclipse 插件时,需要链接使用四个类,关联TextEditor
对象与RuleBasedScanner
,示例代码如下:
如果能推断出某个功能的两个端点,哪些类使用了它,以及哪些类提供它,那么中间过程就可交给计算机去操心。当然,还有其他一些程序能实现这样的功能。通过运行这些程序并做分析跟踪,就能找到作为指针引用链负责“链接”两个类的代码。这样,程序引用就能具体归结到确切实现功能的代码。基于这一理念,MatchMarker 应运而生!
在一项研究中,要求 8 位程序员去构建一个基本的 Eclipse 语法高亮显示功能,高亮显示一种新语言中的两个关键字。该研究为半数参试程序员提供了 MatchMaker 及其基本教程。该教程中的确给出了如何去执行操作,但是其中内容繁杂,并没有多大帮助。对照组历经波折,平均 100 分钟完成。而使用 MatchMaker 的一组很快就摸清了门路,平均只用了 50 分钟。鉴于具有 5 年经验的 Eclipse 专家耗时 16 分钟,这一结果相当不错。
事实上,我非常了解 Matchmaker,因为我读研的第一个月就被安排参与推进该项目。我很喜欢该项目,推动了项目的扩展并支持 Android。但该项目也退步了。几年前,我的导师引进了一名暑期实习生去开发 MatchMaker。但他很快就碰上麻烦,MatchMaker 无法在 Java 8 上运行。
三个观点
第一个观点,我们所使用的工具在很大程度上取决于一些关键个体的选择。尽管Mylyn成为最受欢迎的 Eclipse 插件之一,“反射模型”这一理念仍然籍籍无名。这完全可归因为模型的提出者 Gail C. Murphy 决心投身学术界,而她的学生、Mylyn 的创建者 Mik Kersten,则选择了加入工业界。
编程工具并非一个可将进步视为“某个理念的时代已经到来”的领域。这只会发生在类似理念有很多人研究的情况下。即便该理念并未被某个人所采纳,那么几年后也得到其他人的采纳。而这种竞争在编程工具领域是非常罕见的。
举个例子,一位著名的教授学术休假去创立了一家网站构建工具公司。我曾问他,如果他的理念能打败所有前期同类工具,那么为什么以前没有人做过?他的回答大体意思是,“只有我才能打造此类工具所需的技术”。
第二个观点,当前编程工具的构建方式是存在问题的。在其他计算机科学领域,科研人员和业界从业人员之间应该不存在如此巨大的鸿沟。我此前曾提出,构建工具的难度更多地取决于编程语言的复杂性(编程语言的复杂性,由 C++即可见一斑),而非取决于研究理念。在变革性理念出现之前,如果构建工具的销售量不足以支撑其巨大的固定成本,那么不可能推出任何新的工具。这正是我博士研究致力于简化工具构建的初心所在,也是我对那些不够先进但是免费工具的泛滥痛心疾首的原因。这些工具导致市场低迷,工具开发商难以收回成本。
第三个观点是,作为开发人员,我们应该对工具提出更多的要求。如果你曾考虑过构建一种开发者工具,那么有大量很好的工作可以借鉴。如果你渴求更好的工具,就必须报以期待。
原文链接:
评论