从Java测试代码中提出新语言
2003年8月29日,詹姆斯·斯特拉恩发表Groovy的设计公告,介绍他与鲍勃·麦克沃特正在讨论的新语言。它面向Java虚拟机(JVM),希望让程序员用较简练的动态语言编写脚本和单元测试,同时继续调用、扩展和测试现有Java代码。
斯特拉恩的出发点与测试驱动开发有关:测试程序常比被测逻辑更冗长,编写这些代码占用了大量时间。他欣赏Python、Ruby的表达方式,却希望语言从一开始就紧密结合Java平台。早期构想借鉴序列、映射和闭包,同时保留Java程序员熟悉的外观;公告征求意见时,许多细节仍在讨论之中。
参考:[1]
词法分析器、测试和公开协作
这份公告也留下了实现进度:麦克沃特已着手编写词法分析器,斯特拉恩则开始编写Groovy语言的测试代码,等待编译器与运行时可以执行它们。讨论借助IRC、GroovyWiki和开发者邮件列表展开,读者可向愿望清单提交建议。因此,2003年8月的公开亮相是正在形成的开源语言项目,而不是已经完成的1.0版本。
项目发布记录随后列出2003年12月13日的1.0.0-beta-1、12月27日的beta-2,以及2004年继续推出的测试版。版本号中的“1.0.0”带有beta后缀,表示朝正式版本推进的试用阶段,不能据此把正式1.0发布提前到2003年。
在既有虚拟机上增加表达方式
2004年3月,Groovy以JSR 241进入Java社区进程。原始提案由盖尔·马格努松提交,列斯特拉恩与理查德·蒙森-黑费尔为规范负责人;3月16日至29日的提案审议投票获得通过。目标平台是Java 2标准版1.4及后续版本,适用桌面和服务器程序。
提案的技术路径是把Groovy编译成符合JVM规范的Java字节码,生成普通类文件,而不是另建一套虚拟机。程序可以利用已有Java类库,开发者也能在同一应用中组合两种语言。提案通过意味着开始推进语言规范工作,并不等于已有最终标准;它与2007年的实现版本发布是不同事项。
参考:[2]
用闭包缩短重复动作
Groovy保留传统for循环,也提供把操作作为参数传入方法的写法。例如,3.times { println "第${it + 1}次" }会依次输出“第1次”“第2次”“第3次”。times负责重复三次,花括号内是闭包,隐含参数it依次取0、1、2;字符串中的插值表达式把计数加一后嵌入文字。
这里压缩的是循环控制和输出的书写形式,重复动作本身仍清楚可见。另如列表['甲', '乙'].join('、')得到“甲、乙”:列表可使用Java集合的实现,Groovy增加便捷方法。脚本还可以省去显式声明的入口类和main方法,适合短小任务;这些便利并不表示所有Java源码都能毫无语义差别地迁移。
参考:[3]
从反复修订到正式1.0
Groovy早期发展并非直线推进。苏布拉马尼亚姆的技术书回顾了项目一度受困难拖累的阶段,以及纪尧姆·拉福热、杰里米·雷纳重新推动修补缺陷、稳定语言特性的工作。其后团队与用户共同测试,发布序列从beta转入带JSR标记的版本,再到正式版候选。
2006年12月先后发布两个候选版本。2007年1月2日,拉福热代表开发团队发布1.0正式版公告,并提供发行包及JAR文件的取得方式。官方汇总日志把1.0.0的发布日期列为1月3日,而当时公告本身标注1月2日;公开宣布与发布记录的日期相差一天,应分别保留。
脚本进入实际Java应用
1.0公告列举了候选版的实际测试场所,包括保险业务应用、XWiki第二代引擎、RIFE框架和Spring 2.0的脚本集成。团队强调的用途也超出单元测试:短脚本可以调用Java应用编程接口,Grails则把Groovy与Spring、Hibernate等组件结合,用于Web应用。
另一类用途是把经常调整的业务规则和模板从主程序中分离出来,或以领域专用语言表达业务操作。Groovy早期设计的价值由此落在具体的衔接方式上:保留Java平台及类库,把更简练的脚本、闭包和动态表达嵌入既有开发流程。2003年的设计启动与2007年的稳定发行,分别标记了这条路线的提出和一个可交付阶段。