读完《Scala程序设计》,随便谈一些想法吧
虽然我对Scala还算熟悉,但还是在china-pub上订阅了一本图灵引进的《Scala程序设计》。上上周五在公司收到了这本书,顺手带回家,在路上简单翻了翻。周六用来欢乐,周日懒觉睡觉中午,直到下午才又拿起这本书,不过加上周一上班途中的工夫也算将这本不到200页的小册子浏览完了。这本书的内容本身并没有给我留下太深刻的印象,但我也想谈一些有关Scala语言和其他一些方面的想法。
“编程语言”这东西自然是和“编程”相关,刚出版的8月份《程序员》杂志的专题是“语言”,其中田春(binghe)写了一篇关于Common LISP的文章,里面有这么一句话:
作为一门以编程为职业的程序员,时间是如此宝贵,以至于绝对不能把宝贵的时间浪费在不断跟进各种草率设计的新语言上,而忽略了对编程语言本质和一般编程方法(算法、数据结构上)的理解上。
这句话从道理上来看似乎是没错的,不过给我的感觉多少有些原教旨主义了。或者应该这么说:要理解这句话,还得谈一下“什么是编程语言本质”及“哪些是草率设计的新语言”等话题。我不懂“本质”,各种东西的“本质”我都不懂,就像我理解不了《建筑的永恒之道》对于学习GoF设计模式有哪些帮助一样。但如果你真要我谈一下心目中编程语言的“本质”,我可能会说是“更好地表达人类思考”,“辅助人类解决问题”一样。举个例子,C语言体现了编程语言的本质吗?在我看来,没有,因为它体现的是冯诺依曼机的本质,是操作机器的本质,和“表达人类思考”,“辅助人类解决问题”无关。因为,要不是有冯诺依曼机就不会有C语言;同时,在我看来人类也不会在“思考”时关心指针、地址、堆/栈、偏移量、字节等事物。
当然,如果您是一位C语言粉丝,看到这里也不要急着反驳。首先,我只是说“C语言不能代表编程的本质”,并没有说“不本质就不好了”,也没有对C语言做出“不重要”或是“不值得了解”之类的评价。其次,我不都已经说过我不懂所谓“本质”了嘛。
回到这个话题来说,什么样的语言算是“本质”了呢?按照我的标准,就是能够“更好地辅助人类解决问题”的语言,再通俗地讲,就是生产力更高的语言。比如人们发现C/C++中的内存管理造成了很大的麻烦,于是出现了垃圾收集机制;人们发现C++过于复杂,而Java语言便可以视为是它的一种简化。虽然我一直说Java是种劣质语言,但也必须承认它的历史地位,它在十几年前绝对是一种突破,只不过多年来的不思进取、固步自封让它成为了“现今标准”下的劣质语言——这很正常,因为即便是C# 2.0,在现在看来也是一种劣质语言。语言在发展,它的评价标准也在不断提高。
在刚获得Jolt图书大奖的《Masterminds of Programming》一书中,作者向Anders Hejlsberg问起过有关C#和Java在语言演化方面的问题:
When I compare C# to Java, C# seems to have a stronger push toward evolution. The Java people seem to want a baseline where everyone’s code looks more or less the same. Whether you’ve programmed Java for a decade, never programmed before, or just graduated from a six-month course on Java, all of your code will look the same. C# seems to pull in new ideas from Haskell or from F#. Is there a desire to add new features that people who’ve just finished the six-month C# course haven’t seen and won’t immediately understand?
Anders回答道:
What is it that powers the Internet revolution and the electronic revolution that we’ve seen? It’s the fact that we’re constantly evolving. I bring it back to that. The minute you stop evolving, I don’t know that you’re adding anyvalue. This is, again, taking it to the extreme. Of course, there is value in stability of the platform, but I think you provide that value by ensuring backward compatibility. You are free to get off the bus at C# 1.0 and just not move any further. For those people that reallywant to be more productive and want to build newer kinds of apps like SOA or whatever and get into more dynamic styles of programming—adaptable programs and more declarative styles of programming like we’re doing with LINQ—then you’ve got to evolve or get out of the way, or something else will replace you.
人们对生产力的探索和追求是无止境的,“固步自封”是一种违背潮流的行为。
之所以设计出新的语言,主要原因大都是设计者对现有语言的不满;当然也不排除一些商业上的因素,例如当年Sun迫使微软不得触碰Java语言,于是微软设计了.NET和C#语言与之竞争(无独有偶,Oracle最近又和Google展开了有关Java的专利诉讼)。例如,Groovy在考虑到Java语言的平滑升级的基础上融入了有更好生产力的元素,而F#和Scala都在并发编程和DSL方面给予了加强。那么,它们都是草率设计的语言吗?可能有人说,是的,因为这些语言里的语法糖特别多。那么,语法糖便意味着草率吗?
我的看法是否定的,一个特性是否草率或是是否重要,关键不在于它是不是个所谓的语法糖,而是要看它有没有带来编程思维上的改变,或者说,它有没有遵循语言设计者的文化。我们可以从各种语言找到许多此类有文化语法糖
- C#的Lambda表达式是匿名委托的语法糖,但是它带来/鼓励了函数式编程及无副作用编程的思维。
- Haskell中的“$”运算符,和F#中的“<|”运算符的作用是简单地“改变优先级”,让程序员可以省略括号,写出流畅的代码。
- Scala中的方法调用a.method(b)可以省略点和括号,写为a method b,这样开发人员便很容易写出one day ago这样的DSL。
Scala还有许多用于“省略”或是“替代”的规则,目的就是让程序员可以写出更为漂亮而紧凑的代码,这便是Scala的文化(之一)。Scala是我认为最有机会,也是最适合代替Java的语言。因为从JVM上的语言来说,Jython和JRuby都是“另一种语言”,程序员甚至需要在“Ruby的Date对象”和“Java的Date对象”间进行切换;Clojure是一种类LISP的语言,它的编程模型和思想与Java相距太远;Groovy是Scala的有力竞争对手,因为它考虑到了Java程序员的平滑过渡,只不过它是一门动态类型语言,这点和Java程序员的习惯有所不同;而Scala是一门静态编译型语言,性能很高,能够和Java一样进行面向对象和命令式编程,也可以表现出和Java一样的对象模型——自然还有额外的提高生产力的语言特性。
有些朋友认为Scala过于复杂,难以掌握。关于这点我想说:有利自然有弊,Scala既然可以带来更好的生产力,自然需要您进行额外的学习,从Java语言切换到Scala并非一蹴而就的,但是这些付出在我十分值得,因为Scala是一门挺有想法的语言。再者,Scala真难学吗?或者说,它比Java语言难学吗?在我看来真不见得。这里有一个事实是:Java的语言规范比Scala的语言规范要多得多,因此其实从某些角度来说,Scala要比Java要简单的多。出现这个情况的原因也很容易理解:因为Java是一门十分死板的语言,它需要用大量篇幅来表示各种限制和规定,而Scala只是提供一些最基本的语法描述和变化规则,剩下都是这些规则的自由组合了——此正所谓Scalable。
例如,在Scala中,“1 + 2”这个基本表达式,从概念上说也是一个Int对象上的方法调用,其完整形式为“1.+(2)”。那么,试想在语言规范中,还需要定义次方运算或是求模运算吗?这些篇幅都可以省下了,因为这些“运算符”都已经变成了“类库”,要知道整数之间有哪些运算符,只要去浏览文档就行了。至于“+”方法最终表现为一个加法指令而不是方法调用,这便是编译器在优化时所做的事情了。“语言”有自己的文化,“编译器”也有自己的优化策略。
当然,语言规约的规模并不能直接用于论证语言的复杂度,“变化”有时也会带来复杂度。其实我只是想说,Scala语言并不可怕,作为一个程序员,比这门语言难以掌握的东西有太多了。在C#这边也有人经常抱怨说“C# 3.0太复杂,不能保证团队里人人都会”,对此我的说法是,当年我在创业时,招了几个工资在3000左右的程序员,他们都能在一个星期里学会C# 3.0的新特性(原本就会C# 2.0)——假如说一份能力一份待遇的话,那么您的期望薪资是多少呢?
最后再回到《Scala程序设计》这本书吧,这是本连附录也只有180页的小册子,很明显只能是Scala语言的概述和入门,并没有企图让您精通这门语言。这本书的副标题是“Java虚拟机多核编程实战”,这我认为只是个“噱头”而已,因为这本书对于Scala引以为豪的Actor库也只用了20页不到的篇幅。不过话说回来,即便是《Programming in Scala》这本近800页的,覆盖了Scala语言方方面面的“巨著”,其中关于Actor的那章也只有30多页——因为Scala的Actor模型本身也只是以标准库的形式提供的,且十分简单,并不是Scala的重点。如果您对这方面感兴趣,我觉得更应该关注的是akka这个类库而不是Scala的标准库。而如果要将Actor模型和并发编程的方方面面都讲清楚的话,估计又需要整本书的篇幅了。
总体来说,《Scala程序设计》可以算作是一本“称职”的书,即使您无法在工作中使用Scala语言,甚至您不是个Java程序员,也不妨可以从这本小册子里简单地体会一下这门语言。许多开发人员常说“静态语言”的开发效率如何如何低,其实也只是被Java这门劣等语言给误导了,事实上Haskell、C#,F#和Scala都是静态语言的典范,了解Scala也有助于开阔眼界。
《Programmatic Programmer》里建议开发人员每年学一门新的语言,Scala也是个不错的选择。与此相比,如果让一个C#程序员去学习Java,那投资回报率则实在是太低了。
最后我也在想,可能这种小册子形式的书也是有不少价值的,例如阅读的代价较低,也比较容易快速地翻译引进,而像《Expert F# 2.0》这样的由语言设计者(还是个科学家)亲自编写的砖头,受众面自然会狭窄许多。