聊聊那些美丽的语言

就侃侃我见过的那些美丽的语言们吧。

IT男好像特别喜欢争论,比如 Windows vs Mac vs Unix、Java vs C# vs C++、Vi vs Emacs,这些都老生常谈了。甚至如果你弄混了开源与自由软件,自由软件的拥护者会耐心的给你解释:开源并非自由。

我不是计算机专业科班的,但是从小喜欢,一直都是自己四处看各种东西,很多时候并不是考虑实用,因此别人问我:你学这玩意有用么?我也只能一笑了之。这就是“宅”。有人宅漫画,有人宅美剧,我宅编程语言。你要问,你学这些漫画,能找到工作么?这不是搞笑吗。

好言归正传,想到哪写哪:

要涉猎各种编程语言,有个网站不得不说:Tiobe 的语言排行榜。排行榜这玩意就是看个乐呵,从这个榜单出发,可以开始涉猎之旅。

先说手头上立刻想到的: Python、Haskell、Smalltalk。

Python,Tiobe排名第7。Python在国外IT界,尤其是非MS派里,已经算是class 1的语言了。国内这几年发展相当的迅速。话说04年左右,一小撮最早的Python用户组了啄木鸟中文社区,相信国内的Python程序员对这几个名字肯定不陌生:HD、delphij、zoom.quiet、limodou……。目前很多网络公司都在应用,这里面比较出名的像豆瓣网,大部分代码都是Python开发的。

罗嗦完掌故,说说Python语言本身,这门语言很实用,语法上强制缩进是最大特点,混合了OO、FP的一些元素,有非常好用的列表和字典等内置类型,自带的库很丰富。可以说是一把瑞士军刀。

helloworld:

def main():
    print 'Hello world'
    print [x*x for x in range(10)]

第二个print 里面用了一个 list comperhension,中文大概叫列表推倒。其实,这个用法是从 Haskell 里借鉴来的。

下面侃侃 Haskell

Haskell 是一个标准的学院派的语言,一直在学术圈子里面作研究,被研究。话说70年代经历了 Fortran、Lisp、Prolog、C 等等语言生物大爆炸之后,学术界开始更加关注函数式语言,这块的理论要往前追溯,就要到 Lambda 演算,Haskell Curry 的逻辑理论,等等。我印象里图灵奖得奖演说中,约翰·巴克斯的题目就是:程序能从冯诺依曼体系中摆脱出来么?说的就是函数式语言。这之后出现了大批实验性质的语言,到了80年代,这些学术界的人觉得这样各自为战太浪费,于是决定合力搞一个语言,这就是 Haskell 的诞生。Haskell 的名字就来源于 Haskell Curry 这个人。curry 这个词也很重要,后面会说。

在象牙塔里面悠哉游哉了20来年之后,外面的世界已经翻天覆地了,计算机史上的20年,差不多就像是宋唐演进到明清一般啊。而直到此时,外面的人才逐渐认识了这个闺中MM。她终于得见天日了。

在去年的 Jolt 大奖里,《Real World Haskell》这本书获得了开发类的大奖,现在中文版已经翻译完成了,具体出版日期就不知道了。

国内的情况么,除了几个爱好者自己研究外到没见过成规模的应用,我一般用作些数据统计之类的。

扯完掌故,谈谈语言本身。

Haskell 的特点就是:纯函数式、强类型、惰性计算。所谓纯函数式,就是指一个函数不能有IO操作、全局变量操作,对一个特定输入只能有一个特定的输出,无论调用多少次,无论从哪个CPU上调用,也无论在调用它之前还调用过别的什么,总之只要输入确定了,输出就确定了。各位看官看到这个是不是开始激动了?

我说的激动有两点:这种特性天生就是为多核和并行准备的啊!想想看,现在什么Map Reduce啊,不就是把数据扔到多个CPU让去算么,如果语言能保证纯函数式,那么多核会简单很多。


但是,一个纯函数,不能IO操作,那它怎么读文件,怎么“print 'hello world'”,怎么写数据库啊?别急,Haskell 里面有个叫做 Monad 的东西,就是干这个的。Monad 保证了计算的顺序,也就保证了IO的实现。

但是要把IO操作和纯函数严格的隔离开,怎么办呢?Haskell 的另一个特性:强类型的特性就发挥作用了。

Haskell 里面每一个函数和操作都有一个类型签名,整个程序就像是很多个形状不同的拼版,必须形状匹配才能拼装在一起。任何带有副作用的函数,都会带一个IO的类型标签,这个IO类型标签就像一个戳,只要带上了,任何调用它的函数也必须有IO标签。明白了么?只有带有IO类型标签的函数才能调用另一个带有IO标签的函数,而在IO函数内可以调用纯函数,而反过来,纯函数却不可以调用带有IO标签的函数。

好像很绕啊,hello world 登场吧:

fact :: Int -> Int
fact 0 = 1
fact n = n * fact(n - 1)

main :: IO ()
main = print (fact 5)

阶乘函数就是函数式语言里面的 Hello world :) 。这个fact 函数的类型是 Int -> Int,就是输入 Int 输出 Int,在里面不能进行任何的IO操作。而 main 函数是 Haskell 的程序入口点,它的类型是 IO () ,它里面可以调用 print 这个IO类型的函数,也可以调用 fact 这个纯函数。

说完了纯FP类的,再说说纯OO类的:Smalltalk!

Smalltalk 离开大众视线已经很久了,目前重新受到关注,是因为一个web框架:seaside。就像 Ruby on rails 使 Ruby 大红大紫一样, seaside 也一定程度上唤回了一些人对 Smalltalk 的重新关注。

话说 Smalltlak 不仅是OO理论的鼻祖,也是现代GUI的开创者。窗口、MVC、设计模式、虚拟机、垃圾回收、Block Closure 概念都在 Smalltalk 中发扬光大。Smalltalk 就像一座遥远山林中的殿堂,从中走出的思想,影响了 Java、ruby 等后世的语言。

回头看 Smalltalk,其实它的语法非常的简单,简单到只需要用一张A4纸就可以全写下来,简略的说,就几条:
1. 所有一切皆对象;
2. 对象间通过消息驱动;
3. 代码块 block;
4. 所有对象都是一个类的实例,类本身也是。

基本没了。

等等,那些选择、循环语句呢? 没有,真的没有。语法上没有定义那些。这些东西都是对象上的消息,例如判断语句,就是 Bool 类型对象上的一个方法:

3 > 4 ifTrue: [do this] ifFalse: [do that].

这个的意思是,3>4 得到一个 Bool 类型的对象,Bool 对象上有个 ifTrue:ifFalse: 方法,这个方法有两个参数,分别是一个代码块 Block,由这个方法决定如何执行。循环和这个类似。

看官感觉到激动了么?!我已经激动了。

程序员自己来写语法哦,你可以写出判断、循环,也能写出更复杂的控制逻辑,而且这种定义 Method 的语法,天生就是 DSL(领域特定语言)。所以看现在 Ruby、java 啥啥的整天折腾些 DSL 啊啥的吓唬人,我就暗想,Smalltalk 800年前就这么玩了。

再说说 Smalltalk 特色的东西,它的 Image 是个不得不说的东西,整个运行环境,就是一个 image,说白了就是一个虚拟机,所有的对象、所有的代码和数据都生活在这个 Image 里面。比如运行到一半,保存关闭,传输到别的机器上。第二天在别的机器上再打开,还从昨天关的地儿接着跑。

这几个东西,每个要展开都是几本书都讲不完。今天砖抛了,等玉砸过来。

展开阅读全文

没有更多推荐了,返回首页