【外刊IT评论网】如何学会函数式编程

标签: 心得体会 函数式 纯函数 | 发表时间:2011-08-24 00:34 | 作者:Aqee iBeyond
出处:http://www.aqee.net
本文是从 How to get started with functional programming 这篇文章翻译而来。

上周末,有人问我,如何学会函数式编程。我的回答是:用你现在使用的编程语言写纯正函数。

纯函数唯一的输入是它的参数,唯一的输出是它的返回值。如果你以前从未接触过这个概念,你会以为所有的函数都是纯正的。毕竟,所有的函数都是接受一个或多个输入值,返回一个输出值。但在某些传统编程中,经常会有一些外来的信息流入或流出函数。例如,一个不规范的函数有可能会依赖一个全局变量或一些类成员数据。在这种情况下,函数的行为并不完全决定于它的参数值。相似的,一个不规范的函数有可能会更改一个全局变量或修改数据库。这种情况下,函数除了返回值外,还会附带一些额外操作。

你可以用任何语言写出纯函数,只是有些语言容易写,有些语言写起来比较复杂。例如,没有人会把Fortran当作一种函数式语言,但有些人(M. J. D. Powell)却强制自己在Fortran里要写纯函数。

为什么要写纯函数?纯函数具有亲系透彻性(referential transparency),也就是说,针对相同的输入值,它一定给出相同的输出值。函数输出不依赖系统时间、数据库状态以及任何没有显式的作为参数传入函数的东西。这也表明纯函数易于理解(因此也易于调试和测试)。

你可以一直使用纯函数。但如果你想把一个值放到数据库里,光通过纯函数是实现不了的。或者当你想调用一个随机数发生器时,你可不想它保持亲系透彻性—每次都返回相同的值。但是,在可以用到纯函数的时候,你应该使用纯函数,用纯函数来消除越界联系。完全的纯函数程序是不现实的;有人建议说最佳的纯度系数应该是 85% 。

那么,为什么程序员不大量的使用纯函数呢?一个原因是,纯函数需要更长的参数表。在面向对象的编程语言里,对象可以隐式的依赖对象状态来减少参数数量。对于这更简洁的方法接口,你付出的代价是,你无法只通过方法本身来理解这个方法。调用这个方法时你还需要知道对象的状态。为了获得更短的方法接口而放弃亲系透彻性值不值得?这依赖于你的上下文环境和你的风格,按我的观点,我更愿意用更长的函数接口来换取更纯的函数。

另外一个人们不太喜欢使用纯函数的原因是,把大型数据结构传入函数太麻烦。但这也依赖于你怎么干。你可以只是形式上的把一个对象传输函数,而不是把整个对象按字节拷贝进去。

为了效率,你也可以制造一些假纯度。例如,Mike Swaim最近在一个评论里给出了一个如何利用Memoization让程序的速度提升数个等级的例子。(Memoization是一种缓存技术。当一个函数向系统请求计算某些东西时,它首先看看这个东西是否已经被缓存过。如果是,它会从从缓存里取出结果返回。如果否,它会计算它,然后把输出放到缓存里。)使用Memoization技术的函数严格的说不是纯函数—它的计算操作直接受缓存状态的影响—但这样的函数仍然保持亲系透彻性,如果你给它相同的输入,它总会产生相同的输出。你可以认为称这样的函数为纯函数是一种欺骗,的确也是,但如果你总是纠结于这种事情,那你也知道,完全纯函数是有副作用的。


本文来自外刊IT评论网(www.aqee.net),原始地址:如何学会函数式编程

相关 [it 函数 编程] 推荐:

函数式编程初探

- - 博客 - 伯乐在线
诞生50多年之后, 函数式编程(functional programming)开始获得越来越多的关注. 不仅最古老的函数式语言Lisp重获青春,而且新的函数式语言 层出不穷,比如Erlang、clojure、Scala、F#等等. 目前最当红的Python、Ruby、Javascript,对函数式编程的支持都 很强,就连老牌的面向对象的Java、面向过程的PHP,都忙不迭地加入对匿名函数的支持.

函数式编程思想:不变性

- pippo - 译言-每日精品译文推荐
来源Functional thinking: Immutability. 面向对象的编程通过封装可变动的部分来构造出可让人读懂的代码,函数式编程则是通过最小化可变动的部分来构造出可让人读懂的代码. ——Michael Feathers,Working with Legacy Code一书的作者,经由Twitter在这部分内容中,我讨论的是函数式编程的基石之一:不变性(immutability ).

Dart中的函数式编程

- - 技术改变世界 创新驱动中国 - 《程序员》官网
JavaScript的一个特点是它支持函数式编程. 因为Dart的目标是让人感觉熟悉,现在让我们看看在Dart语言中函数式编程是什么样的. 我们先从一个传统的例子开始,计算斐波纳契数列. 在JavaScript中,大概像下面这样写:. 探索一个语言的函数式编程特性,斐波纳契数列是个很好的例子. 不仅因为它是一个函数,也因为它的递归性质可以展示函数的调用.

学会像函数式编程者那样思考——函数式编程思想:以函数的方式来思考,第1部分

- xf - 译言-每日精品译文推荐
来源Learning to think like a functional programmer——Functional thinking: Thinking functionally, Part 1. 让我们先来扯一下这样的一个话题,你是一个伐木工,在这森林中,你有着一把最好的斧头,这使得你成为了营地中最具生产效率的樵夫.

【外刊IT评论网】如何学会函数式编程

- iBeyond - 外刊IT评论网
本文是从 How to get started with functional programming 这篇文章翻译而来. 上周末,有人问我,如何学会函数式编程. 我的回答是:用你现在使用的编程语言写纯正函数. 纯函数唯一的输入是它的参数,唯一的输出是它的返回值. 如果你以前从未接触过这个概念,你会以为所有的函数都是纯正的.

Clojure 1.3发布,基于JVM的函数式编程语言

- bamerl - ITeye资讯频道
Clojure日前发布了 1.3 版本. Clojure是一个在JVM平台运行的动态函数式编程语言,在JVM平台运行的时候,会被编译为JVM的字节码进行运算,能调用Java的类库,支持并发,与Scala类似. Leinigen或是Maven用户现在可以设置依赖:.    该版本中包含了许多重大的特性和性能改进,比如增强了原生支持、改进了defrecord和deftype、改进了异常报告、可以通过Maven进行编辑和部署,以及绑定Conveyance等.

函数式编程思想:耦合和组合,第2部分

- TONY - 译言-电脑/网络/数码科技
在上一部分内容中,我说明了代码重用的不同做法. 在面向对象的版本中,我提取出了重复的方法,把他们和一个受保护(protected)域一起移到一个超类中. 在函数式版本中,我把纯函数(不会带来边际效应的那些函数)提取出来放到了它们自己的类中,通过提供参数值来调用它们. 我改变了重用机制,把经由继承的受保护域改成方法参数.

【外刊IT评论网】函数式编程很难,这正是你要学习它的原因

- ZB - 外刊IT评论
本文是从 Functional Programming Is Hard,That's Why It's Good 这篇文章翻译而来. 很奇怪不是,很少有人每天都使用函数式编程语言. 如果你用Scala,Haskell,Erlang,F#或某个Lisp方言来编程,很可能没有公司会花钱聘你. 这个行业里的绝大部分人都是使用像Python,Ruby,Java或C#等面向对象的编程语言——它们用起来很顺手.

剧情函数库

- SourBell - 学而时嘻之
(《新知客》,2010年10月). 著名物理学家徐一鸿先生在《可怕的对称》这本书中谈到对称性群的时候提到一个很有意思的笑话. 有一个客人随他的朋友参加一个笑话俱乐部的聚会. 另一个站起来叫道,“S—5”,引得所有的人都笑了起来. 这个迷惑不解的客人问道,这是怎么回事. 他的朋友解释道:“所有可能的笑话,当然不能计细小的差别,都已经被归类编上号了,我们心里都知道这些编号指的是什么.

函数图像(二)

- DreamToTrue - C++博客-λ-calculus(惊愕到手了欧耶)
    今天终于把雏形给做出来了. 主要的方法是牛顿迭代法,把屏幕上的所有点都收敛到函数图像上面. 为了提速,我是用了ThreadTool.QueueUserWorkItem和Parallel.For,还把那颗函数的语法树用Linq.Expression编译成了机器码. 下面的这些图都是二十秒钟左右就可以画出来的了.