下载本文示例代码
Herb:我想,我们有必要在“函数型”编程领域做一个进一步区分,将其划分成两个部分。我非常同意Anders和Erik的意见。我不太同意的是这样的措辞:我们之所以继续使用“命令型”编程语言,是因为这是大家目前所能理解的;通用程序员目前的工作并未取得巨大的成功;市场对于“所有的东西都是表达式,所有的语言都应该是表达式类型的语言”这样的理念已经非常接受了;“函数型”语言是“串行执行”的好药方。我们要想使“函数型”语言运转良好,关键的并不是处理好基本的表达式问题,而是处理好lambda表达式和副作用的问题,关键是能够将表达式作为第一级的编程要素来使用——LINQ也是最近才在做,关键是能够指出lambda表达式和Closure(译者注:函数型编程语言中的一个概念,可以方便地组合函数,返回函数)的副作用。实际上,最后这点目前是缺失的(Anders也附和着:对,对)。这些东西在“命令型”语言中也是要处理的东西。我为什么提这些?因为我觉得说“函数型”语言是方向,目前的“命令型”语言不够好,因此是垃圾,必须要抛在脑后,全面采用“函数型”语言这样的说法不对(译者注:呵呵,对Anders的说法有点急了,毕竟是泡在C 上,对C 有感情的人)。我认为,对于“函数型”语言能够帮助程序员完成哪些工作,目前还不太明了。比如,能够用它写通用代码吗?能够用它系统级代码吗?当然,“函数型”语言有不少我们能够应用的好东西,比如lambda表达式,比如Closure,C#借鉴了,C 也在借鉴,这些语言因此增色不少。关于“函数型”语言还有另一个问题,那就是有两种类型的“函数型”语言,一种是没有副作用的,因此就没有共享的易变的状态的问题;一种是人人都在使用的,对吧(译者注:显然Herb认为“没有副作用”的理想情况是不太可能的)?因为你不太可能说,“瞧,我是完全并发安全的,因为每次我从XX(译者注:听不清)向量中得到一个拷贝,或者我使用XX(译者注:听不清)元素的时候,我都是取得一个拷贝”。确实不错,这里是没有共享的易变的状态,但是是否能够完全并发安全则不一定。
Anders:是的。我的意思是,在类似C#或VB这样的“命令型”编程语言中加入“函数型”结构,能给我们提供“以函数型风格”写库的能力,从而我们就能够非常明确地说,如果你能保证传入的lambda表达式是纯粹的函数,我们就能保证正确地把它分散到若干个线程或者CPU上,最后把它综合起来,给你一个正确的结果,我们能够保证代码运行得更快,同时你还不用作任何编码上的修改。如果你在写一个大大的For循环,我们永远都不可能保证做到前面所说的,此时,“函数型”编程能够提供给你的是一系列表达式,再加上“把代码当作参数传递”,“类型推论和泛型编程可以正确地绑定所有的类型”这些特性,这样你就能更方便地编写“可组合的算法块”。
Charles:这样一来不就削弱了抽象吗(译者注:Charles可能想的是程序员不需要再关心“可组合性”,语言和运行库应该保证这件事,而现在听起来并非如此)?
Herb:呃,我很同意Anders的意见,我想指出的是,当前所有的语言都有意不保证 “没有副作用”。之所以如此的原因是,除非所有的语言都添加一些机制让程序员可以清除副作用,我们这些做语言的人不敢打这个包票。但是,添加这样的机制涉及到众多参加者,大家一起思考、讨论什么是最好的方法的过程会很漫长。我们所做的是相信程序员,因为我们自己不知道。然而,程序员在很多情况下也不知道,因为他写的函数要调用其他的库。这里“可组合性”又浮上水面了,程序员根本不知道他用的库有怎样的副作用。一般说来程序员会再增加一层间接性,但是问题依然存在,没有人能够清楚地知道副作用,除非他拥有涉及到的所有的代码,这就是难题所在。上面这些讨论对“锁”也适用,因为“锁”也是个全局问题,对于“可操作性”是个障碍。
Brian:(译者注:在Herb说话的时候已经很着急地想说了几次)在这点上Haskell做得很好,Haskell是“永远没有副作用”的范例。
Erik:是的,但做到这点的过程也是痛苦的,因为并非所有的情况都一目了然。一旦你的(库)代码有副作用,而且因此使程序员的代码必须按照某种顺序执行(因为副作用的关系,该程序必须先干某事,再干某事),某种意义上你在用汇编语言编写东西,因为程序员将不再能用“表达式 表达式”的方式来写代码,他必须决定先对某个表达式求值,再对另一表达式求值,再把值加起来。因此我认为我们在这点上干得还是不够漂亮。
Brian:现在,我们在“流库”上有例子。好消息是,我们已经有Haskell向你展示如何以“可行性”方面的代价,换来用绝对纯粹的方式来做事。当然,除Haskell外我们有各种“杂牌”语言。呵呵!
(众人均乐)
Charles:这是个供研究的语言吗?
Brian:是的,我们将它设计为供研究用。
Anders:没有纯粹的好或坏,我认为,虽然进展缓慢,我们仍然快到一个令人满意的中间点了。我完全同意说,如果我们确实能够保证函数的纯粹性,生活将会非常美好。最终我们必须要做到。
Brian:在研究领域,大概有20多项工作与此有关——契约语言,契约和限制,等等。
Erik:但是,不少的副作用也并非坏事,如果我的函数使用了一个局部变量,这就是使用了一个状态,但是,函数本身还是纯粹的。如果你想要完全避免副作用,我觉得会非常困难,一些东西可以是局部不纯粹而整体纯粹的。
Herb:回过头,让我们从整体上看看“可组合性”。让我吃惊的一件事是,很多时候,人们甚至都没有意识到这是个问题。他们并没有意识到自己实际上经常碰到这个问题。整个软件工业,整个世界其实已经基于可组合的软件了。在硬件会议上,我经常对硬件公司提到的是(呵呵,通常此时我都是在轰击硬件工业,但是软件业也有同样的问题):硬件的并发问题被仔细地探索过了,而且,当前消除共享易变状态的最好办法就是“锁”;但是,锁是全局的,是一种全局资源,不能被组合;“被锁”是经常发生的事情,而拥有一个锁时,我还能调用任何其他的未知的代码,这就破坏了“可组合性”。说到这里,有的听者往往一脸茫然:这有什么问题吗?我于是指出,好的,你们是否上网下载别人刚刚发布的,自己喜欢的新软件,比如,某个浏览器,3个插件,然后就用呢?大家回答:是啊。于是我再指出,你们是否意识到了,当你们这样做时,经常地,这些软件都是第一次在最终用户的机器上被组合,被使用?既然如此,你们怎么可能对其进行测试?这时,屋子里有百分之十的人会露出恍然的表情,因为此前他们没有想过这个问题:这些软件是第一次在最终用户的机器上被组合,我们怎么进行测试?正因如此,“可组合性”是更加重要的一个问题。更不用说我们现在有AJAX,应用程序,以及众多的其他插件经常被下载,而且被要求在同一个用户界面中协调工作。 查阅关于 架构 的全部文档
Herb:我想,我们有必要在“函数型”编程领域做一个进一步区分,将其划分成两个部分。我非常同意Anders和Erik的意见。我不太同意的是这样的措辞:我们之所以继续使用“命令型”编程语言,是因为这是大家目前所能理解的;通用程序员目前的工作并未取得巨大的成功;市场对于“所有的东西都是表达式,所有的语言都应该是表达式类型的语言”这样的理念已经非常接受了;“函数型”语言是“串行执行”的好药方。我们要想使“函数型”语言运转良好,关键的并不是处理好基本的表达式问题,而是处理好lambda表达式和副作用的问题,关键是能够将表达式作为第一级的编程要素来使用——LINQ也是最近才在做,关键是能够指出lambda表达式和Closure(译者注:函数型编程语言中的一个概念,可以方便地组合函数,返回函数)的副作用。实际上,最后这点目前是缺失的(Anders也附和着:对,对)。这些东西在“命令型”语言中也是要处理的东西。我为什么提这些?因为我觉得说“函数型”语言是方向,目前的“命令型”语言不够好,因此是垃圾,必须要抛在脑后,全面采用“函数型”语言这样的说法不对(译者注:呵呵,对Anders的说法有点急了,毕竟是泡在C 上,对C 有感情的人)。我认为,对于“函数型”语言能够帮助程序员完成哪些工作,目前还不太明了。比如,能够用它写通用代码吗?能够用它系统级代码吗?当然,“函数型”语言有不少我们能够应用的好东西,比如lambda表达式,比如Closure,C#借鉴了,C 也在借鉴,这些语言因此增色不少。关于“函数型”语言还有另一个问题,那就是有两种类型的“函数型”语言,一种是没有副作用的,因此就没有共享的易变的状态的问题;一种是人人都在使用的,对吧(译者注:显然Herb认为“没有副作用”的理想情况是不太可能的)?因为你不太可能说,“瞧,我是完全并发安全的,因为每次我从XX(译者注:听不清)向量中得到一个拷贝,或者我使用XX(译者注:听不清)元素的时候,我都是取得一个拷贝”。确实不错,这里是没有共享的易变的状态,但是是否能够完全并发安全则不一定。
Anders:是的。我的意思是,在类似C#或VB这样的“命令型”编程语言中加入“函数型”结构,能给我们提供“以函数型风格”写库的能力,从而我们就能够非常明确地说,如果你能保证传入的lambda表达式是纯粹的函数,我们就能保证正确地把它分散到若干个线程或者CPU上,最后把它综合起来,给你一个正确的结果,我们能够保证代码运行得更快,同时你还不用作任何编码上的修改。如果你在写一个大大的For循环,我们永远都不可能保证做到前面所说的,此时,“函数型”编程能够提供给你的是一系列表达式,再加上“把代码当作参数传递”,“类型推论和泛型编程可以正确地绑定所有的类型”这些特性,这样你就能更方便地编写“可组合的算法块”。
Charles:这样一来不就削弱了抽象吗(译者注:Charles可能想的是程序员不需要再关心“可组合性”,语言和运行库应该保证这件事,而现在听起来并非如此)?
Herb:呃,我很同意Anders的意见,我想指出的是,当前所有的语言都有意不保证 “没有副作用”。之所以如此的原因是,除非所有的语言都添加一些机制让程序员可以清除副作用,我们这些做语言的人不敢打这个包票。但是,添加这样的机制涉及到众多参加者,大家一起思考、讨论什么是最好的方法的过程会很漫长。我们所做的是相信程序员,因为我们自己不知道。然而,程序员在很多情况下也不知道,因为他写的函数要调用其他的库。这里“可组合性”又浮上水面了,程序员根本不知道他用的库有怎样的副作用。一般说来程序员会再增加一层间接性,但是问题依然存在,没有人能够清楚地知道副作用,除非他拥有涉及到的所有的代码,这就是难题所在。上面这些讨论对“锁”也适用,因为“锁”也是个全局问题,对于“可操作性”是个障碍。
Brian:(译者注:在Herb说话的时候已经很着急地想说了几次)在这点上Haskell做得很好,Haskell是“永远没有副作用”的范例。
Erik:是的,但做到这点的过程也是痛苦的,因为并非所有的情况都一目了然。一旦你的(库)代码有副作用,而且因此使程序员的代码必须按照某种顺序执行(因为副作用的关系,该程序必须先干某事,再干某事),某种意义上你在用汇编语言编写东西,因为程序员将不再能用“表达式 表达式”的方式来写代码,他必须决定先对某个表达式求值,再对另一表达式求值,再把值加起来。因此我认为我们在这点上干得还是不够漂亮。
Brian:现在,我们在“流库”上有例子。好消息是,我们已经有Haskell向你展示如何以“可行性”方面的代价,换来用绝对纯粹的方式来做事。当然,除Haskell外我们有各种“杂牌”语言。呵呵!
(众人均乐)
Charles:这是个供研究的语言吗?
Brian:是的,我们将它设计为供研究用。
Anders:没有纯粹的好或坏,我认为,虽然进展缓慢,我们仍然快到一个令人满意的中间点了。我完全同意说,如果我们确实能够保证函数的纯粹性,生活将会非常美好。最终我们必须要做到。
Brian:在研究领域,大概有20多项工作与此有关——契约语言,契约和限制,等等。
Erik:但是,不少的副作用也并非坏事,如果我的函数使用了一个局部变量,这就是使用了一个状态,但是,函数本身还是纯粹的。如果你想要完全避免副作用,我觉得会非常困难,一些东西可以是局部不纯粹而整体纯粹的。
Herb:回过头,让我们从整体上看看“可组合性”。让我吃惊的一件事是,很多时候,人们甚至都没有意识到这是个问题。他们并没有意识到自己实际上经常碰到这个问题。整个软件工业,整个世界其实已经基于可组合的软件了。在硬件会议上,我经常对硬件公司提到的是(呵呵,通常此时我都是在轰击硬件工业,但是软件业也有同样的问题):硬件的并发问题被仔细地探索过了,而且,当前消除共享易变状态的最好办法就是“锁”;但是,锁是全局的,是一种全局资源,不能被组合;“被锁”是经常发生的事情,而拥有一个锁时,我还能调用任何其他的未知的代码,这就破坏了“可组合性”。说到这里,有的听者往往一脸茫然:这有什么问题吗?我于是指出,好的,你们是否上网下载别人刚刚发布的,自己喜欢的新软件,比如,某个浏览器,3个插件,然后就用呢?大家回答:是啊。于是我再指出,你们是否意识到了,当你们这样做时,经常地,这些软件都是第一次在最终用户的机器上被组合,被使用?既然如此,你们怎么可能对其进行测试?这时,屋子里有百分之十的人会露出恍然的表情,因为此前他们没有想过这个问题:这些软件是第一次在最终用户的机器上被组合,我们怎么进行测试?正因如此,“可组合性”是更加重要的一个问题。更不用说我们现在有AJAX,应用程序,以及众多的其他插件经常被下载,而且被要求在同一个用户界面中协调工作。 查阅关于 架构 的全部文档
下载本文示例代码
微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三微软架构师谈编程语言发展之三
阅读(161) | 评论(0) | 转发(0) |