Hello World
Spiga

编程语言的发展趋势及未来方向(4):动态语言

2010-05-23 22:16 by 老赵, 13036 visits

这是Anders Hejlsberg(不用介绍这是谁了吧)在比利时TechDays 2010所做的开场演讲。由于最近我在博客上关于语言的讨论比较多,出于应景,也打算将Anders的演讲完整地听写出来。在上一部分中,Anders谈及了声明式编程的另一个重要组成部分:函数式编程,并使用.NET平台上的函数式编程语言F#进行了演示。在这一部分中,Anders讨论了动态语言及JavaScript的相关内容,“动态性”也是Anders眼中编程语言的发展趋势之一。

如果没有特别说明,所有的文字都直接翻译自Anders的演讲,并使用我自己的口语习惯表达出来,对于Anders的口误及反复等情况,必要时在译文中自然也会进行忽略。为了方便理解,我也会将视频中关键部分进行截图,而某些代码演示则会直接作为文章内容发表。

(听写开始,接上篇

我下面继续要讲的是动态语言,这也是我之前提到的三种趋势之一。

我还是尝试着去找到动态语言的定义,但是你也知道……一般地说,动态语言是一些不对编译时和运行时进行严格区分的语言。这不像一些静态编程语言,比如C#,你先进行编译,然后会得到一些编译期错误,稍后再执行,而对于动态语言来说这两个阶段便混合在一起了。我们都熟悉一些动态语言,比如JavaScript,Python,Ruby,LISP等等。

动态语言有一些优势,而静态语言也有着另一些优势,这也是两个阵营争论多年的内容。老实讲,我认为结果不是两者中的任意一个,它们都有各自十分重要的优点,而长期来看,我认为结果应该是两者的杂交产物,我认为在语言发展中也可以看到这样的趋势,这两部分内容正在合并。

许多人认定动态语言执行起来很慢,也没有类型安全等等。我想在这里观察并比较一下,究竟是什么原因会让静态语言和动态语言在这方面有不同的性质。这里有一段有趣的代码,它的语法在JavaScript和C#里都是正确的,这样我们便能比较两种语言是如何处理这段代码的。

首先我们把它看作是一段C#代码,它只是用for循环把一堆整数相加,你肯定不会这么做,这只是一个示例。在C#中,当我们使用var关键字时,它表示“请为我推断这里的类型”,所以在这里a和i的类型都是int。

这断代码在执行的时候,这两个值都是32位整数,而for循环只是简单的使用ADD指令即可,执行起来自然效率很高。

但如果从JavaScript或是动态语言的角度来看……或者说对于动态类型的语言来说,var只代表了“一个值”,它可以是任意类型,我们不知道它究竟是什么。所以当我们使用var a或var i时,我们只是定义了两个值,其中包含了一个“类型”标记,表明在运行时它是个什么类型。在这里它是一个int,因此包含了存储int值的空间。但有些时候,例如要存储一个double值,那么可能便需要更多的空间,还可能是一个字符串,于是便包含一个引用。

所以两者的区别之一便是,表示同样的值在动态语言中会有一些额外的开销,代价较高。而在如今的CPU中,“空间”便等于“速度”,所以较大的值便需要较长时间进行处理,这里便损失了一部分效率。

在JavaScript中,我们如果要处理a加i,那么便不仅仅是一个ADD指令。首先它必须查看两个变量中的类型标记,然后根据类型选择合适的相加操作。于是再去加载两个值,然后再进行加法操作。这里还需要进行越界检查,因为在JavaScript中一旦越界了便要使用double,等等。很明显在这里也有许多开销。一般来说,动态语言是使用解释器来执行的,因此还有一些解释器需要的二进制码。你把这些开销全部加起来以后,便会发现执行代码时需要10倍到100倍的开销。

不过由于近几年来出现的一些动态虚拟机或引擎,目前这些情况改善了许多。比方说,这是传统的情况(上图左),如在IE 6或IE 7里使用的非常缓慢的解释器。目前的情况是,大部分的JavaScript引擎使用了JIT编译器(上图中),于是便省下了解释器的开销,这样性能损失便会减小至3到10倍。而在过去的两三年间,JIT编译器也变得越来越高效,浏览器中新一代的适应性JIT编译器(上图右),如TraceMonkeyV8,还有如今微软在IE 9中使用的Chakra引擎。这种适应性的JIT编译器使用了一部分有趣的技术,如Inline Caching、Type Specialization、Hidden Classes、Tracing等等,它们可以将开销降低至2到3倍的范围内,这种效率的提升可谓十分神奇。

在我看来,JavaScript引擎可能已经接近了性能优化的极限,我们在效率上可以提升的空间已经不多。不过我同样认为,如今JavaScript语言的性能已经足够快了,完全有能力统治Web客户端。

有人认为,JavaScript从来不是一种适合进行大规模编程的语言。如今也有一些有趣的工具,如Google Web Tookit,在微软Nikhil Kothari也创建了Script#,让你可以编写C#或Java代码,然后将代码编译成JavaScript,这就像是将JavaScript当作是一种中间语言。Google Wave的所有代码都用GWT写成,它的团队坚持认为用JavaScript不可能完成这样的工作,因为复杂度实在太高了。如今在这方面还有一些有趣的开发成果,我不清楚什么时候会结束。不过我认为,这些都不算是大规模的JavaScript开发方案,而编写C#或Java代码再生成JavaScript的方式也不能算是完全正确的做法。我们可以关注这方面的走向。

在.NET 4.0的运行时进行动态编程时,我们引入了一个新功能:动态语言运行时。可以这样理解,CLR的目的是为静态类型的编程语言提供一个统一的框架或编程模型,而DLR便是在.NET平台上为动态语言提供了统一的编程模型。CLR本身已经有一些支持动态编程能力,如反射,Emit等等。不过在.NET上实现动态语言的时候,总会一遍又一遍地去实现某些功能,还有如动态语言如何与静态语言进行交互,这些都由DLR来提供。DLR的特性包含了,如表达式树、动态分发、Call Site缓存,这可以提高动态代码的执行效率。

在.NET 4.0中我们使用了DLR,不仅仅是IronPython和IronRuby,还有C# 4和VB.NET 10,它们使用DLR实现动态分发功能。因此我们共享了语言的动态能力实现方式,于是这些语言之间可以轻松地进行交互。同样我们可以与其他多样性的技术进行交互,例如使用JavaScript操作Silverlight的DOM,或是与Ruby、Python代码沟通,甚至用来控制Office等自动化服务。

(未完待续)

相关文章

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

35 条回复

  1. yskin
    113.90.82.*
    链接

    yskin 2010-05-23 22:27:56

    先拜这超长的URL,再看文章。

  2. 必填
    123.123.0.*
    链接

    必填 2010-05-23 22:35:00

    还是去看视频好一些!

  3. 老菜
    60.215.31.*
    链接

    老菜 2010-05-24 07:57:42

  4. 老菜
    60.215.31.*
    链接

    老菜 2010-05-24 08:00:00

    @必填: 还是去看视频好一些!

    嗯,视频也看过,形象生动,有气氛。但是讲的太慢,信息量太小。再看看文字版的,可以随时找到关心的内容,有的内容可以随时跳过,有些内容可以仔细琢磨。

    视频和文字各有各的优势。

  5. 链接

    童刚刚 2010-05-24 08:25:23

    今天这个好像没有函数式的那篇来的震撼,没感觉,难道动态太平常了?

  6. 老赵
    admin
    链接

    老赵 2010-05-24 09:10:20

    @老菜

    那是,视频的SEO效果也远不如文字,嘿嘿。

  7. 链接

    Ivony 2010-05-24 12:29:12

    不过我认为,这些都不算是大规模的JavaScript开发方案,而编写C#或Java代码再生成JavaScript的方式也不能算是完全正确的做法。

    认同。。。。

  8. GreatGhoul
    124.114.234.*
    链接

    GreatGhoul 2010-05-24 12:44:21

    原来wave是用gwt写的,gwt性能如何呀。

  9. DeathKnight
    125.118.71.*
    链接

    DeathKnight 2010-05-24 13:24:37

    加油更新啊 每次看一点点太不爽了

  10. JimLiu
    61.150.158.*
    链接

    JimLiu 2010-05-24 13:54:38

    Google Wave的所有代码都用GWT写成,它的团队坚持认为用JavaScript不可能完成这样的工作,因为复杂度实在太高了。

    我怎么觉得JavaScript生产力比Java强?要不就是他们理解为语言的OO特性和命名空间组织能力更能决定它的生产能力,决定语言能否支撑“复杂度太高”的应用。

  11. 老赵
    admin
    链接

    老赵 2010-05-24 14:09:19

    @JimLiu

    不同方面吧,如果说不适合复杂度高的应用,并不一定是指“生产力”,他们应该看中还是代码结构组织能力,还有可能包括静态检查,强类型等东西。

  12. 老赵
    admin
    链接

    老赵 2010-05-24 14:57:10

    @DeathKnight: 加油更新啊 每次看一点点太不爽了

    已经将近50分钟了,差不多了,呵呵。

  13. 老赵
    admin
    链接

    老赵 2010-05-24 19:18:20

    @Ivony

    不过我认为,这些都不算是大规模的JavaScript开发方案,而编写C#或Java代码再生成JavaScript的方式也不能算是完全正确的做法。

    认同。。。。

    我倒觉得,如果是JavaScript的,这样的做法是很合适的,当然不一定说是C#或是Java,可能是另一门语言,尤其是如果可以做到前后端统一开发的话……

  14. 朋友
    121.23.171.*
    链接

    朋友 2010-05-24 21:20:38

    @JimLiu

    Google Wave的所有代码都用GWT写成,它的团队坚持认为用JavaScript不可能完成这样的工作,因为复杂度实在太高了。

    我怎么觉得JavaScript生产力比Java强?要不就是他们理解为语言的OO特性和命名空间组织能力更能决定它的生产能力,决定语言能否支撑 “复杂度太高”的应用。

    原文中并没有提“生产力”这个词吧?这里所讨论的问题并不是语言的生产力或效率的问题,GWT的初衷就是为了解决在大规模基于Ajax的RIA开发中JavaScript难以开发、调试、维护等问题。试想一下工具对Javascript的支持和Java的支持以及开发过程中其它方面比如单元测试、代码覆盖率、重构等方面支持的差距吧。再加上Java语言本身相对于Javascript的可维护性的提高。所有这一切使开发高度复杂的Ajax应用成为了可能。

  15. 朋友
    121.23.171.*
    链接

    朋友 2010-05-24 21:25:24

    @GreatGhoul: 原来wave是用gwt写的,gwt性能如何呀。

    GWT基本类似于一个编译器,把Java代码编译成经google高度优化的javascript,最终在浏览器上运行的还是javascript。所以这个性能最终还是决定于所用的浏览器执行javascript的性能倒底如何。

  16. 朋友
    121.23.171.*
    链接

    朋友 2010-05-24 21:32:45

    @Ivony

    不过我认为,这些都不算是大规模的JavaScript开发方案,而编写C#或Java代码再生成JavaScript的方式也不能算是完全正确的做法。

    认同。。。。

    我倒是觉得对于目前的大规模基于Ajax的RIA开发来讲GWT是最好的解决方案,主要是我也想不到还有什么其它的好办法。能提供一下其它的方案吗?

  17. 链接

    幸存者 2010-05-24 22:19:20

    @老赵: 我倒觉得,如果是JavaScript的,这样的做法是很合适的,当然不一定说是C#或是Java,可能是另一门语言,尤其是如果可以做到前后端统一开发的话……

    如果真是如此,这种情况恐怕也不会持续太久。原生支持C#或Java或是其它语言的浏览器会出现,Javascript的应用场景会回到Ajax出现之前那样。

    无论怎么看,Javascript也不像是一个中间语言该有的样子,用C#或Java来写Javascript更是削足适履。

  18. zhangz
    221.223.100.*
    链接

    zhangz 2010-05-24 23:23:02

    老赵在macbook上用什么工具开发.net呢,虚拟机还是用mono?

  19. 老赵
    admin
    链接

    老赵 2010-05-24 23:43:45

    @幸存者: 如果真是如此,这种情况恐怕也不会持续太久。原生支持C#或Java或是其它语言的浏览器会出现,Javascript的应用场景会回到Ajax出现之前那样。

    几乎不可能。浏览器太多了,估计没有什么语言能够让每个浏览器都实现一遍了,如果只有单个浏览器支持C#或是Java那基本没有什么用的。所以一个中间编译的工具还是很可行的方法。

    其实JavaSript作为中间语言也没什么不可以的啊,其实中间语言没有什么特别的要求,只要图灵完备的语言都能作为中间语言来对待。我还是挺支持用C#写JavaSript应用程序的,只要能力足够。而“能力”方面最关键的地方,可能还是在DOM交互上吧。不过其实现在Flash,Silverlight也好都可以进行DOM互操作,虽然实现方面不同,但是这方面理论上一定不会有问题的。

  20. 老赵
    admin
    链接

    老赵 2010-05-24 23:44:22

    @zhangz: 老赵在macbook上用什么工具开发.net呢,虚拟机还是用mono?

    能用mono就用mono,不能用mono就用虚拟机。

  21. 链接

    facingwaller 2010-05-25 10:01:57

    老赵 最近在研究什么啊?还在F#?

  22. 链接

    Ivony 2010-05-25 10:52:17

    语言并不一定要浏览器原生支持的么。就像HTML4这么多年没有video和audio标签也照样能看电影,听歌一样。

    事实上,我们只是需要一个语言引擎,可以处理<script language="xxx"> ... </script>的情况。这个引擎完全可以作为浏览器的插件存在,这比浏览器原生并且完全一致的实现同一种语言(例如现在的JavaScript)要简单的多。

    而语言引擎,不见得比个FlashPlayer还大。事实上,对JavaScipt过度的优化也会造成浏览器不兼容不是么?

    照Google这条路走下去,迟早有一天浏览器会有不能承受之重的。大量的AJAX,会造成越来越多的性能陷阱以及内存占用。当然Google可以和浏览器厂商扯皮,但这不是解决问题的方法。

  23. 老赵
    admin
    链接

    老赵 2010-05-25 11:22:40

    @Ivony

    我最近有点重新审视了一下JavaScript语言,因为要做一个XX引擎,需要内嵌一门语言,目前准备从JavaScript入手。因为JavaScript本身被设计为一种十分小(规则简单,标准库少),且十分安全(本身无法访问任何外部资源),这些也都有历史发展的因素存在(比如Web开发各组件职责的设计)。如果要引入另一门语言的话,比如Python或Ruby,脚本引擎本身可能是小事,但是类库呢?哪些引入,哪些不引入?引入的话会不会产生安全问题或增大体积,而不引入的话和普通开发人员的体验就差别比较大了。

    Silverlight倒可能是个很不错的尝试,因为它用的是C#语言和.NET开发环境,如果既要考虑开发体验,又要做到体积小不是件容易的事情。这点不像Flash,本身就是平台制定者,相对容易控制许多。不过很早不就也有Gestalt了嘛,但每次要下载好几兆的类库包还是个问题。

    关于JavaScript,我倒其实不太寄希望与语言本身的优化或改进,因为还是要牵涉到多个浏览器。所以我觉得GWT或Script#这种方式可能是更合适和可行的方法。性能的确是一个限制,尤其是在以前,不过现在JavaScript引擎也越来也越强大了,所以这个限制也越来也越小甚至没有了。

  24. 链接

    Ivony 2010-05-25 13:02:08

    @老赵

    我觉得库的问题并不存在,事实上JavaScript离开了DOM和AJAX库,其能力也是非常有限的,现在任何有规模的Web 2.0应用,都离不开各种各样的JavaScript库,例如jQuery。

    既然JavaScript也离不开库,那么python带个函数库又何妨?完全可以和JavaScript一样么:

    <script src="python.cdn.microsoft.com/pythonLite/1.0/pQuery.py"></script>
    
  25. 老赵
    admin
    链接

    老赵 2010-05-25 13:29:20

    @Ivony

    其实用的就是JavaScript的这种简单性。Python或Ruby的话,当然也可以只保留其语法,而去掉它的库。我只是担心,如果把Python引入浏览器,但不配上标准库以后,买账的人会不会多。

    话说你知道Silverlight包含了哪些库吗?

  26. zzfff
    113.141.29.*
    链接

    zzfff 2010-05-25 16:49:04

    @老赵 @Ivony

    不妨“走”另一个极端:WPF XAML Browser Applications (XBAPs),在此,浏览器意义很小,前提是99%的人都买CLI、WPF(最好能提升成标准)的帐。

    我有时在想,浏览器是个多么傻比的玩意啊!干嘛要被那个Bxx套住呢?希望在有生之年冲出这个套套。

  27. zzfff
    113.141.29.*
    链接

    zzfff 2010-05-25 16:56:56

    为什么HTML还不死呢?因为server可以动态生成,client可以动态执行?XBAP理论上(应该)也行吧?!

  28. zzfff
    113.141.29.*
    链接

    zzfff 2010-05-25 23:49:09

    HTML:标记语言;XAML:元标记语言。如果我没记错(或猜错)的话,HTML6将是元标记语言。HTML6?2032年?宇宙已经大爆炸N次了!!

    最重要的是,造语言、虚拟机、平台的牛牛们不够大气、不够自信:Java Virtual Machine、Python、Ruby...完全是小P孩在玩泥巴,瞧瞧m$的:Common Language Infrastructure、Presentation Foundation、Communication Foundation...差点就说:我就是道路、真理、生命了:)

    自信的人不一定成功,不自信的人绝对不会成功。

  29. zzfff
    113.141.29.*
    链接

    zzfff 2010-05-26 11:51:31

    上面太扯蛋了点,虽然我很彪悍,还是得自省下:)

    我其实对“Java Virtual Machine”这个名字很耿耿于怀,因为没“Common Language Infrastructure”大气。想当年,97、98年吧,我也装模作样迷迷糊糊学了点Java,当时它的理想大得不得了,Write once run anywhere,网络就是计算机什么的......恨铁不成钢吧。虽然JVM与CLI两位同志革命尚未成功,我看好后者,也许是主观情绪。

    逻辑混乱,算了

  30. zzfff
    113.141.29.*
    链接

    zzfff 2010-05-26 16:41:30

    回到两位讨论的话题上来。如果CLI(或JVM,或XXX,it doesnt matter,下同)被99%的人认可接受,并且有标准强大的framework library支持,server完全可以返回XAML + Iron* and/or assembly(instead of HTML + JS and/or ActiveX/Applet),这样的话,即便浏览器还存在,它已经被弱化成一个壳了,或者说CLI + DLR + WPF + ...就是浏览器。

    看下现实,感觉是在写科幻小说

    民主唯一的缺点是效率太低,说好听点是晚熟,慢慢熟吧

  31. alex00zoe
    218.186.10.*
    链接

    alex00zoe 2010-10-12 23:24:00

    @zzfff

    我蛮支持你的思想的,呵呵。干嘛要定义那么多不同的语言和范式呢?不都是图灵机在人类语言图景中的具体映射嘛!

    就算有所谓具体机器和具体领域的效率问题,也犯不上各自的语言之间井水不犯河水吧!

  32. 老赵
    admin
    链接

    老赵 2010-10-13 09:07:00

    @alex00zoe

    自行车和汽车都是交通工具,可女人说要买车的时候,你能给她个自行车吗?本质是用来“把握”的,不是用来直接用的,效率太低。

  33. alex00zoe
    202.156.9.*
    链接

    alex00zoe 2011-08-21 21:52:36

    书同文,车同轨。我们希望即使自行车和汽车是不同的,它们的内在原理也能相通。

    下面这个地址不知老赵怎么看呢?

    http://www.semdesigns.com/products/DMS/DMSToolkit.html

    似乎是沟通起各类语言的一种尝试哦

  34. 老赵
    admin
    链接

    老赵 2011-08-21 22:08:19

    @alex00zoe

    没听懂,自行车和汽车内在原理都能算相同啊?

  35. D瓜哥
    218.65.106.*
    链接

    D瓜哥 2012-12-24 20:31:44

    @老赵

    填个建议,文章中有一个错别字:这代码在执行的时候,这两个值都是32位整数。这个断,应该是段吧。

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我