- 浏览: 244251 次
- 性别:
- 来自: 天津
文章分类
最新评论
-
yulanlian:
...
实现在删除数据后,自增列的值连续 -
RonQi:
楼主写的很好,支持原创!
Google Protocol Buffers
——基于对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包含了无数强大的功能,例如语法提示、重构、调试器等。与此相比,编程语言的改进的确很不明显。
在过去50~60年的编程历史中,编程语言的抽象级别 不断提高,人们都在努力让编程语言更有表现力,这样就可以用更少的代码完成更多的工作。我们一开始使用汇编,然后使用面向过程的语言(如Pascal和 C),然后是面向对象语言(如C++),随后便进入了托管时代,语言运行于受托管的执行环境上(如C#和Java),它们的主要特性有自动垃圾收集、类型 安全等。Anders认为这样的趋势还会继续下去,还会有抽象级别越来越高的语言。另一方面,编程语言往往都倾向于构建于现有的工具上,而不会从头写起。 现在出现的编程语言,例如F#、Scala和Clojure等,都是基于现有框架构建的,每次从头开始的代价实在太高。
在Anders眼中,如今影响力较大的趋势主要有三个 (如图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来做到这一点。此时,使用函数式编程语言时的思维观念便会有所不同。 …… (完整文章请关注0 8 期杂志)
(本文来自《程序员》杂志10年0 8 期,更多精彩内容敬请关注0 8 期杂志)
发表评论
-
win7和VS2010下配置OpenGL的方法
2011-01-15 23:45 6405刚装了win7和VS2010。看了下配置OpenGL的方法和以 ... -
用好ASP.NET 2.0的URL映射
2010-12-06 08:31 759简介: URL映射是ASP.NET 2.0中提供的 ... -
.NET加密技术应用
2010-12-06 08:20 771using System; using System. ... -
加密web.config中数据参数的信息
2010-12-06 08:17 825我们都知道web.config可以保存连接字符串, ... -
主题:ASP.NET加上水印
2010-12-02 19:56 809为我们发布的图片加上一个水印,也是我们经常要做的事情,那怎 ... -
asp.net 2.0 读写配置文件
2010-12-01 11:13 1103下面我给出一个简单的例子说明如何使用WebConf ... -
ASP.NET配置文件的读、写操作
2010-12-01 11:03 1316虽然web.config文件是一个XML文件,但是由于权限的原 ... -
使用aspx实现发送email
2010-11-28 22:08 734源代码如下:using System; using Syst ... -
未能加载文件或程序集system.web.extensions解决方法
2010-11-27 09:40 1632未能加载文件或程序集system.web.extensions ... -
asp.net根据域名查ip C#版
2010-10-31 17:04 999网上有类似的教程,但是是asp.net 1.1的版本,这是本人 ... -
如何构造一个C#语言的爬虫程序
2010-10-31 17:03 860C#特别适合于构造蜘蛛 ... -
C#代码与javaScript函数的相互调用
2010-10-31 16:55 1114C#代码与javaScript函数的相互调用 我们通过问答 ... -
C#操作XML的类:xmlHelper例子
2010-10-31 16:31 4455首先,看下这个XmlHelper类库的结构,如下图: 然后, ... -
C#知识点总结_委托篇
2010-10-30 18:10 623C#知识点总结1——委托篇 1.委托概念: 当要把方法传 ... -
调用Windows API
2010-10-30 18:04 1000在.Net Framework SDK文档中 ... -
C#中正确的调用API函数
2010-10-30 18:02 994在C#中经常需要调用一些API函数,那么怎样才能正确的调用AP ... -
用C#和本地Windows API操纵系统菜单
2010-10-30 18:00 1520一、前言 .NET框架是Windows应用领域中一个非常新 ... -
.NET(C#)连接各类数据库代码-集锦
2010-09-05 07:59 12931.C#连接连接Access using System.Da ... -
C#调用rar.exe解压一个rar文件到系统的临时目录
2010-08-31 00:04 1880//取得系统临时目录 string sysTempDir = ... -
C#实现winform软件开机自动启动并最小化到系统托盘
2010-08-31 00:01 4433一、开机自动启动: 拖一个CheckBox 1、软件启动时 ...
相关推荐
C#是一种由C/C++家族中的“组件导向型”语言,由C#之父Anders Hejlsberg设计,他在微软公司担任杰出工程师,负责开发者部门。C#的设计目标是成为下一代稳健且耐用的软件开发语言,同时也注重保护投资,确保代码的可...
《C# 语言规范》是由Anders Hejlsberg,被誉为C#之父的主要作者之一,与Scott Wiltamuth共同编写的权威性文档。这本书深入解析了C#编程语言的各个方面,为开发者提供了详尽的指导。以下是该书涵盖的一些关键知识点:...
C#(读作“C sharp”)是一种简单、现代、面向对象且类型安全的编程语言。C 和 C++ 程序员能很快熟悉它。C# 同时具备“应用程序快速开发”(RAD) 语言的高效率和 C++ 固有的强大能力。 Visual C# .NET 是 Microsoft ...
**C#** 是一种现代的、面向对象的编程语言,由 **Anders Hejlsberg** 和 **Scott Wiltamuth** 共同编著的《C#语言参考》是一本权威性的技术书籍,详细介绍了 C# 语言的核心特性和高级功能。 ##### 1.1 Hello, World...
泛型是现代编程语言中的一个重要特性,它不仅提升了代码的灵活性和复用性,还加强了类型安全性和性能。在C#中,泛型的实现机制确保了高效且安全的代码执行,为开发者提供了构建复杂软件系统的强大工具。掌握泛型的...
C#(读作 "C sharp")是一种面向对象的编程语言,由微软公司开发并由Anders Hejlsberg主导设计。C# 是 .NET 框架的主要编程语言,于2000年首次发布。它的设计受到了C++和Java等语言的影响,旨在提供强大的编程能力...
本书由C#语言的架构师Anders Hejlsberg和设计小组的成员编写,并为C# 2.0进行了更新。全书从C#语言的简介开始,完整并详细地介绍了C# 1.0的技术规范,并介绍了许多C# 2.0的新功能,包括泛型、匿名方法、迭代器、分部...
C#是一种现代、通用的、面向对象的编程语言, 由Anders Hejlsberg和Scott Wiltamuth开发。C#语言是Microsoft公司推出的第一个真正面向对象的编程语言,具有强大的功能和灵活性。 C#语言的主要特点是: 1. modern...
C# 是由 Anders Hejlsberg 和他的团队在 .Net 框架开发期间开发的。 C# 是专为公共语言基础结构(CLI)设计的。CLI 由可执行代码和运行时环境组成,允许在不同的计算机平台和体系结构上使用各种高级语言。 下面列...
C# 之父 Anders Hejlsberg的力作,C# 程序员的圣经。
Deep Inside CSharp---An Interview with Microsoft Chief Architect Anders Hejlsberg
C#在2000年由 Anders Hejlsberg 领导的团队推出,其语法受到了C++和Java的影响,但更加现代化且简化。C#是.NET生态系统的核心部分,广泛应用于Windows桌面应用、Web应用、移动应用以及游戏开发等领域。 1. **面向...
C# 是由 Anders Hejlsberg 和他的团队在 .Net 框架开发期间开发的。 C# 是专为公共语言基础结构(CLI)设计的。CLI 由可执行代码和运行时环境组成,允许在不同的计算机平台和体系结构上使用各种高级语言。
C#由微软公司的研究员Anders Hejlsberg领导开发,旨在提供一种更安全、稳定、简洁和优雅的面向对象编程语言。 - **发展历史**:C#项目始于1998年12月,最初名为COOL(C-like Object Oriented Language),直到2000年...
《QT024-微软C#语言参考》是由Anders Hjlsberg和Scoot Wiltamuth共同编著的一本技术专著,这本书详细阐述了C#编程语言的核心概念和技术,对于深入理解C#及其应用至关重要。Anders Hjlsberg是C#的主要设计者之一,...