[0.0] scala 背后的故事

作者:紫杉
链接: http://www.zhihu.com/question/27332932/answer/36205274
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

一直以来关于Scala究竟是简单还是困难,在Scala使用者之中都有不少争议。Yang Zhang作为Scala的爱好者,委婉的提出Scala内部核心构造过于复杂,他发布这篇文章时已经使用了3年的Scala,之前更是从Haskell,Lisp处出发的。先撇开他的文章不谈,谈谈为什么Scala可能会比较复杂。


Scala是一门给函数式语言和命令式语言搭桥的语言,它同时保有两者的性格。它的发明者Martin Odersky真是编译器的大神,不仅是教授,还是天才。Java目前的编译器javac的现代版本,就是采用他的版本。他当年受邀给javac写一个新版本叫java-generics,最后发现他的编译器不仅比Sun公司团队的更稳定,更易于维护,一个人虐过一个团队,绝对是大神级别。从Javac1.3版本开始,都沿用了马丁的javac编译器。这件事发生在2000年。


马丁·奥德斯基是函数式语言的爱好者,他终生一直在JVM平台上工作。他的第一个语言叫Pizza(1996年),是讲泛型(Generics)带到了JVM上,当时人们宣称把函数式语言的功能移植到JVM平台是不可能,但是马丁就做到了,用了一个叫Pizza的实验语言。正是因为这个语言,才引起了Sun公司的注意。Sun公司核心开发团队的Gilad Bracha and David Stoutamire联系了马丁·奥德斯基,表示了他们的兴趣,让马丁开发Generic Java项目(1998年)。6年之后,马丁·奥德斯基开发的Generic Java (GJ),终于被加入到了Java1.5之中。有人知道为什么Java中的基础数组array[]是没有泛型的吗?马丁在采访中回答说因为最开始写Java编译器的几个人偷懒取巧,最后导致基础数组没法(或者说很难)实现泛型。


如果这里有早期Java用户,就应该知道Java开始攻占大面积市场,成为很稳定而有名的主流语言,正是在1.5(也就是Java5)之后。如果还想了解他的故事,可以去读读Artima杂志对他的采访:The Origins of Scala 这个采访一共有5个部分(叫作Scala的起源)。


目前讨论的比较多的Scala的主流难度一共有两点。第一点是Scala的可读性。很多人,尤其是未曾使用过语言,或者新手抱怨Scala很难读懂,可读性差。这点基本已经被Scala社区给推翻了。理由很简单,如果你不会法语,自然看不懂法文写成的书。不懂Scala自然就读不懂Scala,这很简单。至于新人难以读懂高手写的代码,一些Scala社区高手们说这样最好不过,免得公司实习生乱改他们的代码(笑谈笑谈)。这个的原因主要是高手倾向于写更Scala风格(函数式风格)的代码,而新手(根据不同的背景)可能更习惯于过程式或者命令式的代码。


比如新手写这样一个代码:


val autoList = for (i <- 1 to 10) { //do this task 10 times}

但稍有经验一点的编程者就会写成:


val autoList = (1 to 10).map(i => /*do this task 10 times*/)

这两者基本等同,但不熟悉map用法的新手就会觉得这样的写法非常奇特。


重新回到马丁·奥德斯基的故事。他是函数式编程的爱好者,也想要将更多的函数式编程法宝带入到JVM上。当年他在Pizza(1996年出现,在Java出现仅一年后)就已经将higher-order function(高阶函数),pattern matching(模式匹配)和generics(泛型)带入了JVM。但由于各种原因,Pizza过于实验性质,最终没能流行起来。


但大神非同于常人的地方就是他没有放弃,在2005年的时候推出了Scala,先是一系列的学术论文,An overview of the Scala programming languageType inference with constrained types,Scalable component abstractions


尤其是这最后一篇,探讨了几种OOP的实现,Trait-based OOP和Class-based OOP以及孰优孰劣的讨论非常有趣。Scala基本采用了Trait-based OOP,并且衍生出了很棒的Cake Pattern(蛋糕设计模式),不过这已经不在这个问题的讨论范围内。于是在Scala中,马丁·奥德斯基走得更远一步,将Type Inference(类型推断),Higher-kindered Type(高阶型类)等等带入了Scala。换言之,Scala基本就是一个在JVM上实现了的Haskell,但一不如Haskell简单,二不如Haskell功能完整。这点在这个30分钟的YouTube视频,Rúnar Bjarnason 讲得很清楚:youtube.com/watch? 。不过他在最后还是告诉观众,要对Scala抱有期望,它还是个年轻的语言,会更好的。如果看不到视频,他的意思基本就是:1. Scala的高阶型类支持有限;2. Scala的类型推断不如Haskell强; 3.Scala的尾递归需要额外标注。我对此的回答是,Scala的类型推断基于JVM的限制上,能做到这样的程度已然不错,日后还会改善。Java连尾递归都不优化,所以能够优化一下已经很不错了。


所以说Scala是一门特地为Haskell和Lisp等函数式语言编程者设计的,在JVM上运行的语言,但是大量吸引来的却是Java和C++领域的编程者。这跟Go语言很像,Go语言最初希望吸引C/C++的程序员,最终钓上来一派Python众。语言创造大神们大叫一声苍天何负我。


本来人们认为类型推断等函数式语言的特征不能移植到JVM上,但正如Pizza的存在,马丁·奥德斯基再一次证明人们错了。正如Pizza带来了Java1.5,Scala带来了Java1.8(Java 8)。和Pizza年代不同的是,马丁·奥德斯基非常打算将Scala变得更加普及,不仅成立了公司TypeSafe,还不遗余力的进行推广,同时Java 8只实现了Scala的一小部分功能,并不能完全作为替代品。


所以说Scala困难的第二点就是说Scala的函数式部分困难,命令式程序员转变思维难,了解概念也不容易。这也是vczh为何推荐那两本书的原因。但这也是等同于在说,学会Java的高阶部分难,说Java泛型难,说Java 8的Lambda表达式难,这样的宣称是没有意义的。


所以函数式编程真的困难吗?不困难。这里引用刘慈欣在《黑暗森林》对四维世界的描述,就是大,太大了,太自由了,重回三维世界感觉像要窒息一般。这点基本是函数式语言编程者对使用命令式语言的描述。Haskell和Lisp程序员笑称Java为B&D(Bondage & Disipline 捆绑与管教——SM的一种)语言。他们也经常告诉外界人士,使用函数式语言能让你真正快乐起来,而不是整天抓狂。国内现在很畅销的《黑客与画家》作者Paul Graham 保罗·格拉汉姆就是忠实的Common Lisp爱好者。他在90年代还写了两本Lisp畅销书,现在都绝版,原价20美元,但亚马逊上旧书已经炒到了150美元。


扯远了一点。原问题想预测语言的未来发展方向。我不敢说C++和Java(暗地里我是希望Java赶紧消失掉的,但毕竟不现实)。Scala的未来发展方向有两个。第一,Scala会像Haskell和Lisp一样,成为学术界高智商精英的宠儿。目前已经有在斯坦福、加州伯克利领导下的Scala-nlp项目(ScalaNLP),还有由塔夫茨(Tufts)大学开发的概率编程库Figaro(p2t2/figaro · GitHub),内部消息称UMass正打算发布新一代机器学习库叫Factory,也是全程用Scala编写(上一代叫作Mallet,java编写,以难用著称)。第二个是由于Scala最为出色的Collection(数据结构)操作,以及极快的速度(谷歌的论文宣称它在某些情况比Java更快(Loop Recognition in C++/Java/Go/Scala)),Scala将会成为大数据时代下的专用处理语言而进入大公司(目前竞争者有Python,但Python太慢,有R,但R只是部分数学、统计学家的宠儿,还有MatLab、Octave、Mathematica一类的最多做“原型”,不能大规模实践的软件)。这样的潮流已经有著名的Apache Spark项目,Spark作为新一代Hadoop数据库,由加州伯克利实验室开发,比Hadoop快100倍,而且其中一个分项目是直接在Spark上跑机器学习算法。同样,Twitter,Foursquare公司已经开始大量使用Scala,国内据说豌豆荚也开始采用Scala和Go等语言(这里是豌豆荚平台架构师邓草原 在Scala母公司TypeSafe接受的采访September 9, 2014


但这些远不是Scala的未来,基本只能算是庸人自扰。Scala的未来发展起源于Scala-Macro,2010年马丁·奥德斯基和他的一位PhD学生合作撰写的论文,将把Lisp最为有名的宏(Macro)带到Scala世界中。Scala-Macro给予语言能直接操作编译器的逆天能力,让类啊,限制啊通通失去意义,真正达到随心所欲的地步,目前Scala-Macro还在试验期,新实验版本叫作Paradise(乐园)。


基于Scala-Macro,斯坦福实验室Persavie Parallelism Laboratory(Stanford PPL)正在将Scala作为DSL(Domain-Specific Language 领域语言)语言,利用Scala-Macro将Scala与底层硬件语言搭起桥梁。这些硬件曾经是C++甚至是汇编语言的领域。这个技术叫作Language Virtualization(并不是Virtual Machine,而是Virtual Language)。如果懒得阅读他们的论文,可以看这一个他们制作的幻灯片:on-demand.gputechconf.com


最后我们绕回开头,那位麻省大神所写的,Scala的真实复杂度。它的复杂Scala确实复杂,内部实现也过于夸张,直接导致编译时间过长。但这过长的原因不是因为Scala编译器烂,正是它太强了。不要忘了马丁·奥德斯基是能一人虐翻Sun公司Java团队的大神,为了在JVM上实现函数式功能,他也被迫做出了很多妥协。


同样,Scala的复杂度也源于它对OOP风格的彻底贯彻。Scala的标准库和Java的标准库类似,帮程序员简单的几乎执行任何事情。大量的重载运算符,依靠类型推断(虽然饱受Haskell众的诟病),让静态语言Scala几乎和动态语言类似,但同时又保留了编译时的类型检查功能。这些方便的功能极大的缩减了编程者的时间,让Scala超越Haskell、Lisp等语言成为最具有工程实践潜力的语言,同时又比另一个Lisp在JVM上的实现Clojure快上不止一点。


Scala也许复杂,但不代表学习困难。相较而言,把Python和Scala放在一起,Scala肯定更难,把VB和Java放在一起,Java肯定更难。最后我只能说,使用何种语言,真的只凭个人兴趣爱好,以及与语言是否“合拍”。我有见过用R用的很开心的普林斯顿统计学博士,我也有见过用JavaScript很开心的某国内工程师。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值