代码改变世界

哥谈的是语言,不是寂寞

2010-02-20 21:48  Jeffrey Zhao  阅读(14984)  评论(76编辑  收藏  举报

经常看到一些文章在谈论语言,例如“哪个语言更有前途”,“语言选择是否关键”。我是个语言粉丝,但是看到这些文章总有一些奇怪的感觉。因为在我看来,这些文章谈的东西都不是我眼中的语言——可能与国内技术环境有关,语言本身被淡化了,例如,谈语言的时候涉及更多的却是“平台”方面的内容(例如冯老大的《编程语言的选择并非无关紧要》)。那么我现在便来描述一下我眼中的“语言”该如何谈论吧——下次在我猛砍Java语言时也好有个参考。

语言

语言是给人看的,人们设计出各种各样的语言,最终会通过某些工具变成机器可以执行的形式。人们设计出语言,是为了进行大规模的程序开发,否则使用机器码来0110着写,估计只有神仙才能写出如今动辄数十万数百万行高级语言的项目来——即便是“高手”也得用汇编哪。但可惜的是,如果仅仅使用汇编,估计程序员的思维永远无法跳出“子过程”这个抽象级别,什么面向对象设计,函数式编程几乎无从谈起。人们在学习和生产过程中会引发一些需求,因而需要产生一些工具来辅助学习和生产,而“语言”便是此类工具之一。只有利用高级语言,人们才能有效地把真实事件抽象成计算机这些机器盒子能认识的东西。

显然,不同的语言适合不同的领域——尤其是那些所谓的“领域特定语言(Domain Specific Language)”,因为在不同领域中所需要的思考方式可能会不一样,对于语言来说就有特定的抽象方式与之应对。不过,对于广大程序员来说接触到的更多的应该是“通用目的语言(General Purpose Language)”,例如C,C++,Java,C#,Ruby,Python,F#……它们都是通用目的语言。对于这些语言来说,它们是为了解决广泛问题而存在的。当然,由于通用目的语言的语言特性不同,它们也是有一定“倾向性”的。例如,F#的Workflow特性尤其适合异步编程,而函数式编程语言可能更适合科学计算或金融方面的应用,因为它们和那些问题(业务)的思维方式比较接近——假如使用Java这样的面向对象语言来说可能就要使用一些奇怪的模式了。

因为语言是用来解决问题的,因此在谈论语言的时候,其实我们主要还应该把关注点放在语言抽象或描述事物(包括“思维”等等)的能力上面,以及用它们解决问题的时候是否方便,是否“舒适”——这可能有“感觉”的因素在里面,但的确也有一些客观的,可以衡量的标准在里面。例如《Concepts of Programming Languages》一书中就提出了以下一些标准:

  • 可读性:读代码的次数比写代码要多得多,可读性自然是非常重要的评判标准。例如Perl语言就比Python要难读的多,可谓是一种著名的Write Only语言
  • 可写性:例如,使用Fortran 77这种不支持指针和动态内存管理的语言中,实现一个二叉树结构会很困难。还有,虽然使用while可以实现任何循环需求,但是没有for语句的语言写起来便会麻烦不少。此外,表达同样的逻辑,代码是否紧凑?如C#或Java等需要相当“架子代码”的语言,同样实现面向对象编程就不如F#或Scala来的紧凑。
  • 可靠性:语言特性是否易于写出正确可靠的代码,如异常处理,静态/动态类型,强/弱类型都是和可靠性有关的特性。此外,一些脚本语言,如PHP或JavaScript中经常被人诟病可靠性不佳,便是由于一些操作(如相等或相加操作)过于“宽容”,容易出错。
  • 代价:例如,语言规则是否太多?是否自然?学习起来是否容易?

通俗来讲,我们考察语言,关注点应该放在它的“语言特性”上。语言特性哪里来?自然是语言制定时定下的,例如JavaC#都有其规约(Specification),其中定制了关于语言的方方面面。但是如Ruby和Python,它们都只有各自的“参考实现”(CPython及MRI),并没有明确的规约文档——有人认为这是个比较重要的问题,因此如Ruby社区便开展了RubySpec项目希望定制一个严格的Ruby语言规约。

我认为,语言规约(再扩大一点,也仅仅包括其标准库)是讨论语言,比较语言的唯一依据——这也是我在谈论语言(如讨论Java语言之低劣)的思考准则。

平台

当然,语言设计的最终目的是让计算机进行计算,因此我们不可能回避其他方面,仅仅谈论语言规约。我这里把除了语言规约外语言实现的其他方面统称为“平台”。因此,这个平台其实包括多种东西,例如:

  • 将程序文本转化为二进制形式的:编译器(包括解释器,Linker等等)。打个比方,主流C++编译器有VC++,GCC;C#编译器也有微软实现的CSC及Mono上的MCS。同样的源文件交由不同的编译器,得到的结果会有不同,而最终也会影响程序性能等因素。但是,我们可以简单认为,这些编译器最终生成的结果是符合一个统一标准的,也就是说它们得到的结果可以用相同的规则来识别与执行。
  • 运行时也是平台的重要组成部分。例如,使用微软的CSC编译出的程序集可以在微软的CLR或Mono提供的运行时上执行,同样Sun的Java编译器生成的Byte Code也可以在Sun和IBM两种JVM上运行。由于运行时实现不同,所涉及的标准库也有不同,其程序执行的性能和稳定性都会有所区别。
  • 在不同的执行环境下,可以利用的周边事务是不同的。例如,IronPython便非常容易和.NET程序进行互操作,而JRuby便可以利用Java平台上的各类框架。而一个C语言程序本身也是一个合法的Objective-C程序,但是在Mac OS X上编写Cocoa程序利用的也是不同的环境(不确定,求证)。
  • 技术以外的方面,如社区活跃度等等。

当然,上面举的编译器和运行时都是最为典型的例子。事实上,很多平台并没有如此明显的划分,它们的编译器和运行时都是一体的。例如Python语言的实现有传统的CPython,.NET平台上的IronPython,Java平台上的Jython,以及追求比CPython更高性能与灵活性的PyPy。此外,JavaScript语言除了在各浏览器引擎中不同的原生实现外,现在又有了神奇的Node.js,可以在服务器端使用JavaScript编写高性能的服务器端程序。

当我们谈论到一门语言“能做什么”,“性能如何”时,往往就是在讨论的就不(仅仅)是语言,而是平台了。语言里的概念和平台实现并非完全相关,例如在Scala语言中,1 + 2并不是一个表达式,它其实表示的是1.+(2),也就是一个整型对象上的“加”方法的调用。但是在编译器的实现上,出于性能考虑就会尽量将其编译成原生的整数加法操作。当然,语言中的很多部分也在真切地影响其平台相关的部分,例如C语言的目标是系统语言,因此便尽可能的接近计算机体系结构,没有高级的语言特性,要把很多细节都交由程序员去控制。而如C#或Java这样的语言,从语言特性上就注定了其执行环境需要GC能力,这样对于一些空间密集型的场景可能就比不上如C语言般精细控制所带来的性能;同样,C/C++这样的语言可能并不适合高性能计算,因为它的语言设计注定了会遇上“别名检测(alias detection)”方面的问题,于是编译器便无法像一些无副作用的函数式编程语言那样进行自动并行,或者生成充分利用系统缓存的高性能指令。

吵架

以上,我承认语言与其平台其实有着密切联系,但是在很多情况下我们可以忽略平台而仅仅谈论语言

例如,因为CLR和JVM的性能和可靠性是相同的(您有不同意见?嘿嘿,这里不讨论这个),所以我们便可以比较C#与Java(甚至F#与Scala);因为Rails和Django的能力不分上下,因此我们可以比较Ruby和Python语言在业务逻辑实现方面的优劣;因为它们都在JVM上执行,因此我们便可以引发Java,Scala,JRuby,Jython,Jaskell,Groovy及Clojure的混战。由于我们“求同”,那么“存异”也就有了意义,因为此时语言也是进行技术选型的重要方面了。

语言引发的争吵不计其数,这点有目共睹。我写这篇文章的目的也是希望可以减少这方面的无谓争论。例如我在猛砍Java时,有朋友会回应到:

  • 做项目不能只考虑语言——没错,这并不影响我说Java语言差,我也不想以此让您来用.NET。
  • JVM成熟——没错,但这并不代表Java语言就好了,您可以用Scala,Clojure等语言。
  • 语言不重要,谈语言层次太低了——呃,吵不过您,我妈叫我回家吃饭,吃好饭我就洗洗睡了。
  • ……

其实有时候,我也只是想单纯讨论一下语言罢了——哥谈的是语言,不是寂寞

广告时间

大腕云集的QCon Beijing 2010又要开始了,本次QCon更增加了语言这个主题:

以前,语言还几乎等同于平台,选择了平台也就自然而然地确定了语言。如今,在相同的平台或运行时上已经有多种成熟语言可供选择。以前,语言常被认为是一种单纯的工具。如今,语言更进一步被赋予了文化的意味。正因为如此,目前越来越多的团队在语言的选择上投入了更多的考虑,甚至已经在多种语言的混合编程上获得了成功经验。那么,您是否想了解他们为什么选择这门语言,他们在语言的设计、选择或使用方面又有哪些体会的呢?相信这部分内容可以让您满意。

继去年大受好评的“豆瓣网架构变迁”之后,洪强宁将带来Python语言在豆瓣网中的使用案例。同时,被孟岩誉为年轻一代四大高手的邓草原也会比较Scala与Erlang两者的Actor模型在生产环境下的效果。此外还有一些不知名的老外,如Paul King(Groovy顶级贡献者、《Groovy In Action》的作者)会讨论“动态语言的敏捷开发实践”及“Groovy中的强大功能”,JCP主席Patrick Curran也会来谈论有关一致性测试方面的话题。

现在拨打订票热线还可以享受XXXX的优惠,机不可失,失不再来,您还在等什么,还不赶快订票?