《程序员》8月刊最新上市:新语言,新特性 2010世界杯,我的Android之旅
28

C#之父Anders Hejlsberg演讲解读:编程语言大趋势

作者: wuzhimin 分类:选题策划   阅读:39,273 次 添加评论

——基于对C#之父Anders Hejlsberg演讲的总结


文 / 赵劼

程序设计离不开编程语言,但是编程语言在国内的大环境中似乎一直是个二等公民。国内的计算机教育和工程培训,似乎一直在宣传“语言不重要,重要的是思想”、“语言一通百通”等观点,甚至在许多人眼中,语言的讨论完全是不入流的,但其实编程语言与工具、框架或开发方法等一样,都对生产力有着重要的影响。事实上,语言的发展历史比其他方面更为悠久,并且在过去十几年,甚至最近几年中都依然在不断的碰撞和演变。期间一些新的语言诞生了,而另一些在当时看来阳春白雪的语言和编程范式也重新获得了重视。

Anders Hejlsberg是微软的Technical Fellow,担任C#编程语言的首席架构师,也参与了.NET Framework、VB.NET和F#等语言的设计与开发。几个月前,Anders在比利时TechDays 2010及荷兰DevDays 2010分别作了一场演讲,阐述了他眼中的编程语言的发展趋势及未来方向,本文便对他的观点进行了总结。

大约25~30年前,Anders开发了著名的Turbo Pascal,这是一套集语言、编译器及开发工具于一体的产品,也是Anders进入编程语言领域的起点。Anders谈到,当年Turbo Pascal所用的Z-80和如今的计算机已经不可同日而语。与那时相比,如今的机器已经有大约10万倍的外部存储容量,1万倍的内存大小,CPU速度也有大约1000倍的提高。但是,如果我们比较如今的Java代码及当年的Pascal代码,会发现它们的差别其实并不大。Anders认为编程语言的发展非常缓慢,期间当然出现了一些东西,例如面向对象等,但是远没有好上1000倍。事实上,近几十年来的努力主要体现在框架及工具等方面(如图1)。例如.NET Framework里有超过一万个类和十万个方法,与Turbo Pascal相比的确有了超过1000倍的增长。类似的,现在的IDE包含了无数强大的功能,例如语法提示、重构、调试器等。与此相比,编程语言的改进的确很不明显。

图1  近几十年来语言、框架及工具的发展

图1 近几十年来语言、框架及工具的发展

在过去50~60年的编程历史中,编程语言的抽象级别不断提高,人们都在努力让编程语言更有表现力,这样就可以用更少的代码完成更多的工作。我们一开始使用汇编,然后使用面向过程的语言(如Pascal和C),然后是面向对象语言(如C++),随后便进入了托管时代,语言运行于受托管的执行环境上(如C#和Java),它们的主要特性有自动垃圾收集、类型安全等。Anders认为这样的趋势还会继续下去,还会有抽象级别越来越高的语言。另一方面,编程语言往往都倾向于构建于现有的工具上,而不会从头写起。现在出现的编程语言,例如F#、Scala和Clojure等,都是基于现有框架构建的,每次从头开始的代价实在太高。

在Anders眼中,如今影响力较大的趋势主要有三个(如图2),分别是声明式的编程风格(包括领域特定语言、函数式编程)、动态语言(最重要的方面是元编程能力)以及多核环境下的并发编程。此外随着语言的发展,原本常用的面向对象语言、动态语言或是函数式等边界也变得越来越模糊,例如各种主要的编程语言都受到函数式语言的影响。因此,多范式程序设计语言也是一个愈发明显的趋势。

图2  影响力较大的三个趋势

图2 影响力较大的三个趋势

声明式编程与DSL

目前常见的编程语言大都是命令式(Imperative)的,例如C#、Java或C++等。这些语言的特征在于,代码里不仅表现了“做什么(What)”,而更多表现出“如何(How)完成工作”这样的实现细节,例如for循环、i += 1等,甚至这部分细节会掩盖我们的最终目标。在Anders看来,命令式编程通常会让代码变得十分冗余,更重要的是由于它提供了过于具体的指令,这样执行代码的基础设施(如CLR或JVM)没有太多发挥空间,只能老老实实地根据指令一步步地向目标前进。例如,并行执行程序会变得十分困难,因为像“执行目的”这样更高层次的信息已经丢失了。因此,编程语言的趋势之一,便是能让代码包含更多的“What”,而不是“How”,这样执行环境便可以更加聪明地去适应当前的执行要求。

关于声明式的编程风格,Anders主要提出了两个方面,第一个方面是DSL(Domain Specific Language,领域特定语言)。DSL不是什么新鲜的玩意儿,我们平时经常接触的SQL、CSS、正则表达式等都属于DSL。有的DSL可能更加专注于一个方面,例如Mathematica、LOGO等。这些语言的目标都是特定的领域,与之相对的则是GPPL(General Purpose Programming Language,通用目的编程语言)。Martin Fowler将DSL分为外部DSL和内部DSL两种。外部DSL有自己的特定语法、解析器和词法分析器等,它们往往是一种小型的编程语言,甚至不会像GPPL那样需要源文件。与之相对的则是内部DSL。内部DSL其实更像是种别称,它代表一类特别API及使用模式。

XSLT、SQL等都可以算作是外部DSL。外部DSL一般会直接针对特定的领域设计,而不考虑其他方面。James Gosling曾经说过:每个配置文件最终都会变成一门编程语言。一开始你可能只会用它表示一点点东西,慢慢地你便会想要一些规则,而这些规则则变成了表达式,后来你可能还会定义变量,进行条件判断等,而最终它就变成了一种奇怪的编程语言。这样的情况屡见不鲜。现在有一些公司也在关注DSL的开发。例如以前在微软工作的Charles Simonyi提出了Intentional Programming的概念,还有JetBrains公司提供了叫做MPS(Meta Programming System)的产品。最近微软也提出了自己的Oslo项目,而在Eclipse世界里也有Xtext,所以如今在这方面已经有不少尝试。由于外部DSL的独立性,在某些情况下也会出现特定的工具,辅助领域专家或是开发人员编写DSL代码。还有一些DSL会以XML方言的形式提出,利用XML方言的好处在于有不少现成的工具可用,这样可以更快地定义自己的语法。

内部DSL往往只代表一系列特别的API及使用模式,例如LINQ查询语句及Ruby on Rails中的Active Record声明代码等。内部DSL可以使用一系列API来“伪装”成一种DSL,利用一些流畅化的技巧,例如像jQuery那样把一些方法通过“点”连接起来,而另一些也会利用元编程的方式。内部DSL还有一些优势,例如可以访问语言中的代码或变量,以及利用代码补全、重构等母语言的所有特性。

DSL的可读性往往很高。例如,要筛选出单价大于20的产品,并对所属种类进行分组,降序列出每组的分类名称及产品数量。如果是用命令式的编程方式,可能是这样的:

var groups = new Dictionary<string, Grouping>();

foreach (Product p in products)

{

if (p.UnitPrice >= 20)

{

if (!groups.ContainsKey(p.CategoryName))

{

Grouping g = new Grouping();

g.Name = p.CategoryName;

g.Count = 0;

groups[p.CategoryName] = g;

}

groups[p.CategoryName].ProductCount++;

}

}

var result = new List<Grouping>(groups.Values);

result.Sort(delegate(Grouping x, Grouping y)

{

return

x.Count > y.Count ? -1 :

x.Count < y.Count ? 1 :

0;

});

显然这些代码编写起来需要一点时间,且很难直接看出它的真实目的,换言之,“What”几乎完全被“How”所代替了。这样,一个新的程序员必须花费一定时间才能理解这段代码的目的。但如果使用LINQ,代码便可以改写成:

var result = products

.Where(p => p.UnitPrice >= 20)

.GroupBy(p => p.CategoryName)

.OrderByDescending(g => g.Count())

.Select(g => new { Name = g.Key, Count = g.Count() });

这段代码更加关注的是“How”而不是“What”,它不会明确地给出过滤的操作方式,也没有涉及到创建字典这样的细节。这段代码还可以利用C# 3.0中内置的DSL,即LINQ查询语句来改写:

var result =

from p in products

where p.UnitPrice >= 20

group p by p.CategoryName into g

orderby g.Count() descending

select new { Name = g.Key, Count = g.Count() };

编译器会简单地将LINQ差距语句转化为前一种形式。这段代码只是表现出最终的目的,而不是明确指定做事的方式,这样便可以很容易地并行执行这段代码,如使用PINQ则几乎不需要做出任何修改。


函数式编程

Anders提出的另一个重要的声明式编程方式便是函数式编程。函数式编程历史悠久,如当年的LISP便是函数式编程语言。除了LISP以外还有其他许多函数式编程语言,如APL、Haskell、ML等。函数式编程在学术界已经有过许多研究,大约在5~10年前许多人开始吸收和整理这些研究内容,想要把它们融入更为通用的编程语言。现在的编程语言,如C#、Python、Ruby、Scala等,都受到了函数式编程语言的影响。

使用命令式编程语言写程序时,我们经常会编写如x = x + 1这样的语句,此时我们大量依赖的是可变状态,或者说是变量,它们的值可以随程序运行而改变,可变状态非常强大,但随之而来的便是“副作用”问题,例如一个无需参数的void方法,它会根据调用次数或是在哪个线程上进行调用对程序产生影响,它会改变程序内部的状态,从而影响之后的运行效果。而在函数式编程中则不会出现这个情况,因为所有的状态都是不可变的。事实上对函数式编程的讨论更像是数学、公式,而不是程序语句,如x = x + 1对于数学家来说,似乎只是个永不为真的表达式而已。

函数式编程十分容易并行,因为它在运行时不会修改任何状态,因此无论多少线程在运行时都可以观察到正确的结果。假如两个函数完全无关,那么它们是并行还是顺序执行便没有什么区别。当然,现实中的程序一定是有副作用的,例如向屏幕输出内容,向Socket传输数据等,因此真实世界中的函数式编程往往都会考虑如何将有副作用的代码分离出来。函数式编程默认是不可变的,开发人员必须做些额外的事情才能使用可变状态或是危险的副作用,与之相反,C#或Java必须使用readonly或final来做到这一点。此时,使用函数式编程语言时的思维观念便会有所不同。……(完整文章请关注08期杂志)


未完的部分还有这些内容:

动态语言与元编程

并发

总结


(本文来自《程序员》杂志10年08期,更多精彩内容敬请关注08期杂志)

《程序员》8月刊精彩内容预告:http://www.programmer.com.cn/3742/

《程序员》订阅:http://book.csdn.net/programmer/


56 Responses to “C#之父Anders Hejlsberg演讲解读:编程语言大趋势”

  1. [...] 编程语言的发展趋势及未来方向 七 [...]

  2. 曾国 说:

    这段代码更加关注的是“How”而不是“What”
    应该是
    这段代码更加关注的是“What”而不是“How” ?????

  3. 小王 说:

    挺好

  4. 一条柴 说:

    精彩!

  5. TT 说:

    目前我们在写how,
    如果真的写what的时候,编译器将会为我们做how。
    这样我们的工作机轻松了。编译器则变得更加强大。

  6. shuizhiyun 说:

    谁不说此哥回归到易博龙了吗,怎么不像啊

  7. vx 说:

    期待函数式编程,递归的世界

  8. obullxl 说:

    越来越简单,更多的API,更少的编程。

  9. test 说:

    艾, 国内怎么没有这样的人物呢?

  10. 云云 说:

    数学家是不懂命令式编程的

  11. jsc 说:

    不错,又了解了一些语言的内容!

  12. 陈传义 说:

    未来程序语言的方向是并发,我们通常认为并发是底部的事情,关注的是细节。相反,如果我们能够提供更高一级的抽象语言,如文中提到的声明式编程和函数式编程,并发对Developer将会变得更加容易。
    国内的IT企业都很现实,特别是对于企业级项目来说,技术是次要的,而业务是最重要的。但往往最终却被套进的业务的无底洞,为什么?这个原因需要我们去反思。

  13. Jackerxff 说:

    有多少人知道他就是Delphi之父,C#之父?神一级的人物
    看看Borland传奇吧

  14. 大学生 说:

    个人认为C#是一种很的发展潜力的语言

  15. 尴尬 说:

    呵呵,当初的Delphi之父又摇身一变成了C#之父了。
    这再一次证明了一个真理,当编程水平到达一定高度的时候,你将跳出语言的束缚,从而真正看到我们所关注的不应该是纠结学习某种语言,真正重要的是思想。
    当然,这有个前提,那就是你已经处在告别菜鸟水平的阶段。
    如果你是个刚上路的程序员,那么请选择一种比较容易入门的语言,这样你将事半功倍,当你还什么都不懂的时候,千万别学别人去谈什么思想,那只会让你觉得空虚。老实的敲代码才能让你进入第一次蜕变。

  16. 老赵 说:

    @曾国:
    这段代码更加关注的是“How”而不是“What”
    应该是
    这段代码更加关注的是“What”而不是“How” ?????
    ======================================
    你说得没错,文章的确错了……

  17. googya 说:

    自己掌握得不好就说这个不重要!重要吗,不重要吗?

  18. 唐伟伟 说:

    好的啊

  19. tianjun 说:

    电脑都会自己how了
    还要程序员做什么?
    说:我要软件?然后软件自动出来了?

  20. vistamac 说:

    需求很明确,但是目前还没有任何一种语言能解决所有的需求,所有怎么做还得靠程序员来思考啊

  21. TK312.NET 说:

    未来编程语言的发展趋势 ?

  22. jechy 说:

    强帖前排留名!

  23. jackwei 说:

    牛的不行的人物,膜拜天神

  24. 非死不可 说:

    若有所思,若有所悟,略有所动

  25. jasmingo 说:

    我不懂了,那以后搞程序的门槛不是越来越低?更加像流水线操作员,按照SOP,根本不知道HOW,而只需知道WHAT.

  26. 杨博 说:

    我不赞同Anders的说法,作为被微软从Borland收买的人,这样的演讲的客观性值得怀疑

  27. 无尽碧空 说:

    语言已经间接地说明需要解决的问题,具体如何解决,应该由解析器去处理。SQL是成功语言的样例。它使我们摆脱了对文件的繁琐操作,而直接获得了所需要的数据查询、处理的结果。在每个专业领域,都应该设计、实现自己的”SQL”的知道如何处理HOW, 这样对于使用者而言,就能够专注于需要处理的领域问题,而不是忙着写琐碎的代码。

  28. Sam 说:

    我晕。。怎么看都是在说自己的语言比其他语言有多少优势。。从来不拿他说的重点问题中其他语言来对比。。而是拿自己的长板和别人的短板比。
    客观性太低。。

  29. genius 说:

    看的不太明白

  30. 李超 说:

    有点晕,不是太明白呵呵

  31. 袁道昆 说:

    到时候 ,程序员就只是个历史名词了,、、、

  32. 哈哈哈 说:

    任何语言都有其弱的一方面。

  33. 路人甲 说:

    我觉得c语言完全够用了, linux内核, GNU的那一套,大多数广泛应用,被广泛移植到win平台下的开源工具,都是用c写的。不得不承认,微软的开发环境,尤其是visual stdio 2005之后, 简直是完美,但是隐藏了太多的东西, 做出来的东西效率却不如GNU的产品。对程序员来讲,花费一些时间了解操作系统底层, 了解编译原理, 了解一些被微软极力隐藏的东西,是绝对值得的。程序员是个职业, 很多人要花费15年以上的时间停留在技术岗位上, 如果从c学起, 从底层学起, 打好基础, 是一个非常好的选择。

  34. 路人乙 说:

    38楼的,我觉得我们停留在猿人时代就可以了,有猎打,有肉吃,何必进化成现代人

  35. 路人丙 说:

    现代人的什么舰母,导弹,飞机,坦克,全都不是铁做的吗?所以我们每个人要先学会怎样打铁,因为这更接近于事物的本质,我们吃口饭,一定要象农民伯伯一样先学会种稻子,不然你不配吃饭

  36. 嘻嘻嘻 说:

    我也想设计个语言来

  37. 卢峥 说:

    估计现在软件语言还走在合久必分的时代,开始走多元和细化。

  38. guoapeng 说:

    var result = products

    .Where(p => p.UnitPrice >= 20)

    .GroupBy(p => p.CategoryName)

    .OrderByDescending(g => g.Count())

    .Select(g => new { Name = g.Key, Count = g.Count() });

    我很奇怪,用java不能优雅的实现上面这段代码吗?

    拿一段极端丑陋的java代码(没有任何封装)来和DSL比较,不能说明问题。

    虽然我非常尊敬Anders Hejlsberg ,但是我对这篇文章的真实目的表示怀疑。

    这篇文章怎么看怎么像变相地给.net平台打广告。

  39. netlover2008 说:

    尺有所短寸有所长,过程和结果同等重要。打个比方,现在有很多小型航母配件,小型航母旧了,直接换配件即可;现在要造大型航母怎么办?还得从头开始。

  40. smallfish6 说:

    how是趋势

  41. C_CPP_ASM 说:

    也许我复古,不过对于这些越来越“高级”的语言我的确没啥兴趣。因为对于深入学编程而言,它们掩盖和处理了太多底层细节,使得新手会对计算机这个东西的更本质的认识很模糊,并不利于长远发展。如果仅从应用上来说,也许还不错。哈哈,我爱元老级的编程语言.

  42. wisenwu 说:

    38,39,40楼的回复很亮啊。
    不过我比较赞同38楼!,嘿嘿

  43. 老赵 说:

    @guoapeng
    我很奇怪,用java不能优雅的实现上面这段代码吗?拿一段极端丑陋的java代码(没有任何封装)来和DSL比较,不能说明问题。
    ============================
    事实便是的确不能,Java没有C#的Extension Method,Lambda Expression等语言特性,的确实现不了这些。具体可以看我博客(点名字上的链接即可)上的Why Java Sucks and C# Rocks系列。

  44. QQ41140110 说:

    将会得到更好更快的发展

  45. F 说:

    看起来不错的文章,有点深奥。

  46. li 说:

    bu cuo 有点看不懂啊

请评论

preload preload preload
京ICP备06065162