加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

编程的宗派

发布时间:2016-01-12 11:19:59 所属栏目:语言 来源:简书网
导读:总是有人喜欢争论这类问题,到底是“函数式编程”(FP)好,还是“面向对象编程”(OOP)好。既然出了两个帮派,就有人积极地做它们的帮众,互相唾骂和鄙视。然后呢又出了

代数数据类型(algebraic data type)。所谓“代数数据类型”,其实并不如普通的类型系统(比如Java的)通用。很多代数数据类型系统具有所谓sum type,这种类型其实带来过多的类型嵌套,不如通用的union type。盲目崇拜代数数据类型的人,往往是因为盲目的相信“数学是优美的语言”。而其实事实是,数学是一种历史遗留的,毛病很多的语言。数学的语言根本没有经过系统的,全球协作的设计。往往是数学家在黑板上随便写个符号,说这个表示XX概念,然后就定下来了。

Tuple。有代数数据类型的的语言里面经常有一种构造叫做Tuple,比如Haskell里面可以写(1, "hello"),表示一个类型为(Int, String)的结构。这种构造经常被人看得过于高尚,以至于用在超越它能力的地方。其实Tuple就是一个没有名字的结构(类似C的structure),而且结构里面的域也没有名字。临时使用Tuple貌似很方便,因为不需要定义一个结构类型。然而因为Tuple没有名字,而且里面的域没法用名字访问,一旦里面的数据多一点就发现很麻烦了。Tuple往往只能通过模式匹配来获得里面的域,一旦你增加了新的域进去,所有含有这个Tuple的模式匹配代码都需要改。所以Tuple一般只能用在大小不超过3的情况下,而且必须确信以后不会增加新的域进去。

惰性求值(lazy evaluation)。貌似数学上很优雅,但其实有严重的逻辑漏洞。因为bottom(死循环)成为了任何类型的一个元素,所以取每一个值,都可能导致死循环。同时导致代码性能难以预测,因为求值太懒,所以可能临时抱佛脚做太多工作,而平时浪费CPU的时间。由于到需要的时候才求值,所以在有多个处理器的时候无法有效地利用它们的计算能力。

尾递归。大部分尾递归都相当于循环语句,然而却不像循环语句一样具有一目了然的意图。你需要仔细看代码的各个分支的返回条件,判断是否有分支是尾递归,然后才能判断这代码是个循环。而循环语句从关键字(for,while)就知道是一个循环。所以等价于循环的尾递归,其实最好还是写成特殊的循环语句。当然,尾递归在另一些情况下是有用的,这些情况不等价于循环。在这种情况下使用循环,经常需要复杂的break或者continue条件,导致循环不易理解。所以循环和尾递归,其实都是有必要的。

好好先生

很多人避免“函数式vs面向对象”的辩论,于是他们成为了“好好先生”。这种人没有原则的认为,任何能够解决当前问题的工具就是好工具。也就是这种人,喜欢使用shell script,喜欢折腾各种Unix工具,因为显然,它们能解决他“手头的问题”。

然而这种思潮是极其有害的,它的害处其实更胜于投靠函数式或者面向对象。没有原则的好好先生们忙着“解决问题”,却不能清晰地看到这些问题为什么存在。他们所谓的问题,往往是由于现有工具的设计失误。由于他们的“随和”,他们从来不去思考,如何从根源上消灭这些问题。他们在一堆历史遗留的垃圾上缝缝补补,妄图使用设计恶劣的工具建造可靠地软件系统。当然,这代价是非常大的。不但劳神费力,而且也许根本不能解决问题。

所以每当有人让我谈谈“函数式vs面向对象”,我都避免说“各有各的好处”,因为那样的话我会很容易被当成这种毫无原则的好好先生。

符号必须简单的对世界建模

从上面你已经看出,我既不是一个铁杆“函数式程序员”,也不是一个铁杆“面向对象程序员”,我也不是一个爱说“各有各的好处”的好好先生。我是一个有原则的批判性思维者。我不但看透了各种语言的本质,而且看透了它们之间的统一关系。我编程的时候看到的不是表面的语言和程序,而是一个类似电路的东西。我看到数据的流动和交换,我看到效率的瓶颈,而这些都是跟具体的语言和范式无关的。

在我的心目中其实只有一个概念,它叫做“编程”(programming),它不带有任何附加的限定词(比如“函数式”或者“面向对象”)。我的老师Dan Friedman喜欢把自己的领域称为“Programming Languages”,也是一样的原因。因为我们研究的内容,不局限于某一个语言,也不局限于某一类语言,而是所有的语言。在我们的眼里,所有的语言都不过是各个特性的组合。在我们的眼里,最近出现的所谓“新语言”,其实不大可能再有什么真正意义上的创新。我们不喜欢说“发明一个程序语言”,不喜欢使用“发明”这个词,因为不管你怎么设计一个语言,所有的特性几乎都早已存在于现有的语言里面了。我更喜欢使用“设计”这个词,因为虽然一个语言没有任何新的特性,它却有可能在细节上更加优雅。

编程最重要的事情,其实是让写出来的符号,能够简单地对实际或者想象出来的“世界”进行建模。一个程序员最重要的能力,是直觉地看见符号和现实物体之间的对应关系。不管看起来多么酷的语言或者范式,如果必须绕着弯子才能表达程序员心目中的模型,那么它就不是一个很好的语言或者范式。有些东西本来就是有随时间变化的“状态”的,如果你偏要用“纯函数式”语言去描述它,当然你就进入了那些monad之类的死胡同。最后你不但没能高效的表达这种副作用,而且让代码变得比过程式语言还要难以理解。如果你进入另一个极端,一定要用对象来表达本来很纯的数学函数,那么你一样会把简单的问题搞复杂。Java的所谓design pattern,很多就是制造这种问题的,而没有解决任何问题。

关于建模的另外一个问题是,你心里想的模型,并不一定是最好的,也不一定非得设计成那个样子。有些人心里没有一个清晰简单的模型,觉得某些语言“好用”,就因为它们能够对他那种扭曲纷繁的模型进行建模。所以你就跟这种人说不清楚,为什么这个语言不好,因为显然这个语言对他是有用的!如何简化模型,已经超越了语言的范畴,在这里我就不细讲了。

我设计Yin语言的宗旨,就是让人们可以用最简单,最直接的方式来对世界进行建模,并且帮助他们优化和改进模型本身。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读