武夫提笔——席卷世界Nodejs之初步对比:与opa各占几分春色?

Node 近年来风卷残云,在世界各地风起云涌。进入新公司后,阴差阳错作为一个后端工程师开启了猛攻node的进程。不想,进展神速,现在已在node技术栈上开发出了公司的即时消息系统。在安营扎寨的那些日夜里,稳打稳扎、挑灯夜战的经历让我想把其中的所想所得记录下来,这个想法在心里扎根儿颇久了。

这其实是我从业以来的第一篇正正经经的技术博客。初入行时,曾经在博客园开垦了第一锄头,当时的疑似站长还跑来我的博客树立典型示例性地鼓励了一下,我原本以为自己会在那里搭起枝繁叶茂的花园,结果,刚转行的我实在干涸枯竭,不敢东拼西凑生拉硬扯。

没成想,今天查找资料的时候,突然进到这篇文章,在对比node & opa。文章底下还没有任何人点赞,作为一对 counterpart,我觉得它们显然被轻视了。对比的做法已经显示了生态视角。开博的冲动瞬间成苗。此文作为培养自己的开始。是为武夫提笔志。

原文:http://www.csdn.net/article/2012-03-05/312756

      导读:一个标准的网络项目包括在网络框架下的服务器编程语言、客户端的JavaScript代码和带查询语言的数据库(如SQL)等等。要掌握、装配和整合的技术真是不少。难怪很多开发者在他们输出“Hello world”之前就已经厌倦了。很多工具开发者都意识到这样是行不通的,他们开始寻求更全面地整合其中的一些方面(Google的Web Toolkit就是此类努力的成果)。在动态编程和敏捷开发主导的领域, Node.js和Opa是两种现代典型的全面Web解决方案。两者都具有事件驱动的特性使得它们非常适合编写实时网络应用。让我们来仔细分析比较一下这两种技术的区别吧。

1.Node.js vs Opa:网络框架终极PK

OpaNode.js:区别在哪儿?

Node.js是建立在Google V8 JavaScript引擎之上的网络服务器框架。它是事件驱动的,采用异步输入输出来最小化其成本并最大化其可扩展性。Ryan Dahl在2009年开始研发它,尽管目前有整个团体在贡献力量,但它仍是团队的主要力量。Node.js让开发者能够用客户端使用的语言JavaScript在服务器端编码,目前由一家叫做Joyent公司提供赞助。

Opa是一个开发网络应用的平台。它既是编程语言,同时也是将所有特性高度整合起来的runtime engine。它用的异步模型和Node.js类似,但却采用了全新的静态类型、编译方式和函数语言,是专门为Web设计的。它的开发工作始于2007年,由MLstate公司赞助。

这两种技术有一些共同点:它们都是开源的;编写“Hello world”这个网络应用只需几行代码(实际上在Opa中只要一行);都致力于Web而不是泛型编程;语法很相近,标准库也非常有可比性。

同样的特性,同样的用例,难道Node.js和Opa就真的相似吗?其实不是的,这篇文章将带领大家挖掘这两者之间“不小”的差别。

Opa vs Node.js:网络聊天测试程序

为了说明和比较这两种语言,我们用一个实例,它也正成为一个网络框架或语言的标准测试程序,那就是Web聊天。它非常合适,因为它包含了大量的客户机——服务器通信。

下面我们分别展示用Node.js和Opa编写的聊天程序的截屏,前者是由Node.js作者Ryan Dahl亲自编写,后者是Opa开发者Frederic Ye编写。Node.js chat app是展示这种语言的典型的例子,而Opa chat app则是纯粹为做比较而写的。

Node.js chat app

Opa chat app screenshot

Opa vs Node.js:生产效率

开发者生产效率是选择一种语言非常重要的考虑因素。如果你能快速开发的话,你就能做一些改革创新了。你可以很快创造出原型并保持对市场和用户需求的快速反应。

用SLOC(软件代码行数)作为标准比较生产效率有很多弊端,但它可以粗略估计出编写一个程序需要花多少精力。我们不看生硬的数字,而是展示出这两个程序源代码的全景图(去掉注释之后的)。其中Node.js写的程序我们只展示了client.js和server.js,剩余的文件可以参考标准库。左为Opa编写,右为Node.js编写。 

(图片没找到--武夫)

很明显,Opa要简洁得多,这归功于它比Node.js更贴近于自然语言。例如,Opa分布模型提供的是分布对话的原语,这使得在客户机之间或客户机与服务器之间建立异步通信变得非常简单。

Opa vs Node.js:构建用户界面

Node.js和Opa都用(X)HTML和CSS来构建用户界面。当然,两者都可以在那层之上构建库和抽象物,但它们都不强制这样,允许直接、完全控制标记。

Node.js对HTML没有任何特殊支持,仅仅是字符串之间的连接(就像这个)。这种方法存在一些问题。首先开发人员无法验证其正确性,如未封闭的标签、错字,只有在测试时才会被发现。但更重要的是,这可能暗藏着严重的安全隐患。由于HTML被作为字符串处理,这就要求开发者非常小心,不允许XSS的侵入。

另一方面,Opa中的HTML是一种数据类型(不是基本类型,被当做语言标准库的一部分来开发),对语法有特殊支持并使开发者更容易编写。尽管表面上看起来它只是很符合审美,但它的内涵却远不止这些。实质上,上述的问题都已经被解决了:不合语法的语句会被编译器检测出,语言本身提供了内置保护以防止XSS通过规避HTML中的某些值侵入。

下面,我们展示一下从两种语言中截取的相同片段。

Node.js vs. Opa: SideBySide SLOC 1

Opa vs Node.js:服务器/客户机端的区分和通信

由于Opa和Node.js都能同时用在客户机和服务器端的编程,看看它们怎样处理客户机和服务器之间的通讯应该是一件非常有趣的事情。

Node.js提供了一种直接的方法。服务器和客户机的区分在源代码阶段就已经确定了,一些文件包含在用户端的网页上,另一些在服务器上被Node解释。因此,聊天程序同时包含了server.js和client.js这两个文件。

在Opa中,客户机和服务器端的代码之间没有明确的区分。开发者只管写程序代码就行,Opa编译器会分辨出哪部分代码发给客户机,哪部分发给服务器。当然,开发者可以通过预设函数来影响这一结果。因而,在客户机和服务器之间交换代码就像增加或更改一些指令那样简单。这就是为什么Opa的聊天程序只包含一个文件:main.opa(本例中,为了清楚,所有的函数都加上了注释)。

由于Opa提供了这样的位置透明度,它的通信就建立在一个更高的抽象层次。开发人员所要做的就是依据呼叫方和被叫方的位置来简单调用函数和Opa编译器,并把它们当做本地函数调用或远程过程调用来实施。

这是Node.js聊天代码的片段和Opa中对应的部分。

Node.js vs. Opa: SideBySide SLOC 2

2.Opa vs Node.js:出现错误了怎么办?

Opa vs Node.js:出现错误了怎么办?

众所周知,写代码并不是编程的最后一步——有趣的事往往发生在测试和调试的时候。因此,只有看看这两者在此情况下的对比才算真正公平。实际上,我们需要考虑三方面的问题:语言如何检测错误;对调试的支持;对测试的支持。本文中我们不看测试方面,因为两者在这方面实在太接近了。下面我们从调试功能入手。

在Node.js中开发者用JavaScript同时为客户机和服务器编写代码。而在Opa中,客户机端的JavaScript是从更简洁的Opa代码自动生成的。用户可以选择node-inspector或V8 debugger——Eclipse中Google Chrome开发者工具的一部分,来调试Node.js程序。Opa的情况更加复杂一点,因为现在还没有一款专用的调试工具。而且客户端的代码是自动生成JavaScript,因而,代码的可读性会更低(尽管编译器中有缓解这一问题的选项)。

另一方面,多亏它的编译器提供的静态类型(和很多不需要程序员注释的静态类型不同,Opa有完整的类型推断)和静态分析,Opa才能就错误检测作出承诺。原则上,那意味着它要能够在运行程序之前就检测出大量的错误。为了实际检验,我们在Node.js和Opa的代码上做了很多试验。我们添加了一些常见的错误并观察发生了什么。

我们从函数名这种简单错误开始。Node.js程序中,我们在一个显示当前在线用户数的函数中用lenght代替了length。然后我们重新运行了这个程序,发现直到代码被执行时错误才被检测出来——本例中是当用户进入或离开聊天室调用上述函数时才出现。我们由此可以联想到在不常被调用的函数中,这样的错误是不容易被发现的。错误在JavaScript调试器中只显示为:

GET http://localhost:8001/join?_=1327952561187&nick=akoprowski 400 (Bad Request)

并指向相应Ajax请求发生的地方。要想将这个错误和错误代码联系起来不花点时间,没有一定调试经验的人恐怕是难以完成的。

接着我们又在Opa的代码中安排了同样的错误,Opa不让我们运行这个有错误的程序并报告了如下错误:

File "src/main.opa", line 152, characters 21-28
Expression has a record type incompatible for access to field lenght. […]
Hint: Perhaps you meant length or merge?

我们又试了一些用户自定义数据类型,在Node.js和Opa定义的聊天信息中用txt代替text。结果是一样的:在Node中显示运行错误,没有指出错误所在;Opa中却是详细的错误信息。

然后我们决定看看错误的HTML会发生什么,这是两种语言在界面上的重要构件。在Node.js显示聊天信息的表格中,我们用“,”代替第二个封闭标签,结果程序照样工作但显示却出现偏差(现代的浏览器非常善于“修复”标记错误)。我们还尝试了其他类似的标记错误,其中的一些在输出结果中很难找到缺陷。

在Opa的例子中,我们没有用表格,但却在服务器/客户端区分和通信这段代码中植入了这个错误,得到了一下清楚的错误信息:

Hint: File "src/test.opa", line X, characters X-X
Open and close tag mismatch

在尝试其他变量错误时也得到了类似的编译时期错误。

最后,我们试了一下算术错误。在Node.js和Opa中都有计算内存使用的函数,简单起见,我们将第二次出现的数字1024用字符串“1024”代替。结果很类似,Ajax中不确定的运行时期错误和Opa中如下的编译错误:

File "src/main.opa", line 91, characters 28-41.
Function was found of type 'a, 'a -> 'a but application expects it to be of type int, string -> 'b.
Types int and string are not compatible.

尽管对于从未使用过Opa的人来说上面的错误信息也许还不够明确,但对于熟悉的人来说,简直就是清楚地不能再清楚了。

总的来说,我们认为这些结果是很令人吃惊的。一大类Node.js中需要花大精力去测试和调试的程序错误在Opa中都被自动检测出来了,并且都报告出有用的错误信息(大部分时候)。我们还只是停留在表面,因为Opa实际上可以检测出更多除了上面讨论过的错误。

这点不应当被忽略,因为它可能是区分Opa最重要的特性。它还反应了Haskell程序员多年前就知道的事实:采用一种设计完善的语言可以一次性就写出几乎全对的代码,并在测试和调试环节省下大量的时间。

3.结论

Node.js和Opa都统一了客户机和服务器编码,它们的持续流行表明现在的Web实在是太复杂了,编程模型需要重新定义和简化。尽管Node.js是在现存流行的JavaScript语言上的创新,但Opa给那些想要花时间学习一门新语言的人提供了帮助。

文章出自:developer.com

注:本文未经授权或允许,不得转载。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值