为脚本语言平反-JavaScript篇(1)

导言

在支付宝有一个奇怪的组织叫pCLUB,是一群programmer讨论问题的公共博客(没有对外开放哈)。最近呢,孔宣同学发起一个话题,提出要为种种脚本语言“平反”。他提到说:

我发现,现在脚本语言也深受第一印象所苦。一谈到脚本语言,人们作何反应?

  • 「运行速度很慢」
  • 「只能写一些玩具小程序」
  • 「没什么好用的IDE」
  • 「调试很困难」

所以,这个平反一方面是诉苦大会,一方面则是一场脚本语言的Show。这件事情挑动了我的神经,这十多年来,JavaScript不也一直承受着种种不公平的待遇么?从写框架库到写书,我一直对这门语言充满着热情与隐忍,而现在,孔宣同学挥了挥手,pCLUB的兄弟们就冲上来了,摆出了种种不同的脚本语言的特性,而其间,居然没有这个世界上最用得最多的——我想这样说并不过分吧——脚本语言!天理昭昭日月可鉴太上老君扔了金刚圈圈——啥米意思我也不知道——哈哈,下面就来诉诉苦,以及做下Show。

另,注:孔宣,蔡学镛是也;愚公,笨人是也;百支,支付宝内部员工的一个培训是也。其它略语或别称,不详述了。

为脚本语言平反

百支期间,有虚竹同学介绍技术部,说到整个公司作技术开发工作的,有三块,XXX、YYY和ZZZ。我记性不好,记不得虚同学讲的有啥,反倒记住了他讲的没有什么。比如说,我后来才知道产品部也只有三两个人是M(Manager)系列的,其它的都是P(Programmer/Product/Project)系列上的员工,所以也算是搞技术的。当然,按虚同学严格的讲法,这些还不涉及代码,不算“程序开发者”,所以不提。但当时我就问虚同学了啊,那为什么X/Y/Z里面,没有前端(UED)部门的呢?前端做开发呀。虚同学不好意思地笑笑,若有所思地自言自语到:对呀,他们也做开发的呢。

所以呢,在很多人的印象里面,非但如孔宣同学所说的:脚本语言效率不高、没有好的工具、只能写玩具代码之类,更有如虚同学者,不认为用脚本是在写程序的,大有人在呢。这其中误解最甚的,就是前端开发,以及他们使用的JavaScript了。为什么呢?因为前端开发来源复杂,有从界面设计出身的,有半路出家的,有做客户端开发的……这不算什么,最重要的是,他们所使用的那个语言,叫JavaScript的那个,根不正苗不红,面向过程也不是,面向对象又不象,最常见的情况下,就是在网页中按下来按钮然后弹出来一个“Hello”(连World都没有)……所以,“前端不是做开发的,是‘画’界面的”成为了一种基本观念了。

绕回来。我来做做JavaScript的平反工作。其实在N多年前,我就开始了在JavaScript上做一种尝试,就是将它的“基于原型继承的面向对象”,改成“基于类继承的面向对象”。因为我从Delphi出身,所以自然觉得“有类,是对象之始”。很自然地想做这样一种工作。同样的,觉得“万物皆对象”,当然要把它改造得跟Delphi一样,跟Java一样,这样最好。所以就去做了,这个项目做成开源的,叫Qomo。在Qomo中的代码可以这样写:

var obj = TMyObject.Create();
obj.showMessage('hi');

大家一看就知道,这个是Delphi的路子:对象obj,是从TMyObject这个类上创建出来的。类继承的关系,也是通过一个名字Class()的函数来维护的。当然,还实现了调用父类方法的inherited,getter/setter,以及最著名的“类构造与实例构造”分为两个阶段的体系。接下来,在上面这一基础上,Qomo还进一步地把类似COM的Interface做出来了——这包括“接口既是声明,也是实现”这个复杂的活儿。例如可以这样做:

TMyObject = Class(TObject, 'MyObject', IMyObject, IObject, IInstance);

obj = TMyObject.Create();
intf = QueryInterface(obj, IMyObject);
intf.showMessage('hi');

也就是说,Class()声明中,表明TMyObject 实现了三种接口,所以可以最终从obj的这个实例中通过QueryInterface来取到这些接口(的一个引用)。除了表明“对象/类是否包含某个接口”之外,上面得到的接口还可以直接调用showMessage()方法,这个方法即是obj自身的方法——这就是“既是声明,也是实现”的含义。

最后,Qomo还在上面的基础上,实现了面向切面编程(AOP)、面向模板编程(TOP/GP)等等模式。在开始计划用JavaScript来描述基本的GoF模式时,我终于停下来了。我发现,在这一条路上,我走到了尽头。再做下去,不过是更多语言的特性的实现而已——仅是重述别人的东西,有什么意义呢?

从一年半以前,Qomo开启了一个小小的子项目,叫QoBean。这个项目研究的方向,是“元编程(meta programming)”,就是“实现语言的语言”。JavaScript自身的确有这样的能力,因为JS之父,就写了几十K的代码,在JS上实现了一个新的JS——这被称为语言的完备性。QoBean这个项目开始于2007.12.31,从这个贴子可以看到它最初的状态:启动一个最小化Qomo项目-QoBean!

然后呢,QoBean所要做的事情,即是解决“语言如何产生”的问题。这个问题,QoBean很快的就交了答案。包括:

这样,QoBean就停步在了2008.07.25。停下来的原因是:QoBean做完了这些,却不知道如何表现它——它有什么用呢?

前些天孔同学一直在讲DSL。那么,如果QoBean实现了meta programming,能不能实现DSL呢?一个基本的DSL框架,在JS里面有多复杂呢?于是,这里开贴来讲这个话题。上面是水货,下面才是干的。之所以讲那么多水货,是因为下面的DSL实现基于“QoBean的元语言系统”,上头有两篇文章链接,大家可以先点进去看看。在后面我讲的时候,只会提个大概,不讲这方面的细节了。

下一篇:
为脚本语言平反-JavaScript篇(2)