编程界有一位传奇人物——王垠,介绍一下他的退学经历,对,你没听错,退!学!经!历!:
更传奇的是他的「40行代码」。据说,他层公开过一段40行的代码,并宣称这是他上半生最重要的杰作,曾经耗费顶级专家多年的研究,知乎上有专门的讨论:
https://www.zhihu.com/question/20822815
从这几个经历,我们大概可以推测王垠这个人:
这么一位程序员大牛+重磅写手,在网络上写了几篇深远影响的文章:
其中有一篇跟本文的要说的内容有关——《面向对象编程和函数式编程的问题出在哪里》,这篇文章他将面向对象编程,和函数式编程并列,对两种编程进行了比较和点评。文中的重点,是批评了纯函数式编程。
文本不讨论这篇文章,主要是聊一聊到底什么是「函数式编程」。
点进来的很多同学,应该和我一样,都是数据/统计出身,捣鼓比较多的是SAS/ R,后来转向Python,发现了lambda、map、reduce这些「奇怪」的东西。这说明,你已经开始了函数式编程的体验。
为了呈现函数式编程的概念,我们将编程思维分成「平凡的世界」和「函数的世界」,从实例对比中了解函数式编程。
另外,由于Python是一种通用性编程语言,它支持函数式编程,因此本文的代码实例都用Python来举例。
在「平凡的世界」中,我们一般都是怎么写代码的?以前学SAS的时候看到过一句话:
一门编程语言,只要能实现分支和循环,就能够完成几乎所有的运算。
这么说来,我们在平时编程中无外乎用下面这几个语句:
而在「函数式编程」的世界中,这些将全部用函数来实现!!比如:
匿名函数lambda、Map函数、Reduce函数。
基本上,这几个函数就可以实现任意的Python程序了!我们通过实例来认识一下:
匿名函数:lambda表达式
lambda表达式,又叫匿名函数,它用来创建一个函数,取代def这个功能。
比如,定义一个函数,返回两个参数x+y的值, 在「平凡的世界」里,我们这么写: def add(x, y): return x + y print add(1,2) 用lambda表达式,我们可以这么写: add=lambda x,y : x + y print add(1,2)
因此,lambda表达式的格式提炼如下:
func = lambda 参数: 调用参数的表达式
Map函数
Map函数,是用函数的方式来实现一个循环运算,类似for的功能:
比如,现在有一个list=[2, 4, 6, 7, 8],想对里面每个元素进行平方,生成一个新的new_list。 在「平凡的世界」里,我们这么写: list = [2, 4, 6, 7, 8] new_list = [ ] for i in list: new_list.append(i*i) 返回的结果是: [4, 16, 36, 49, 64] 用Map函数,我们这么写: sqr = lambda a: a*a print map(sqr, [2, 4, 6, 7, 8]) 返回的结果、: [4, 16, 36, 49, 64]
因此,Map函数的使用格式提炼如下:
new_list = Map(func, list),将list中每个元素都进行一个func函数的计算,生成一个新的list
Reduce函数
这个我用的比较少,简单介绍一下,它是对一个数组的元素,进行从左到右进行一个累计的计算。
比如,有一个list=[2, 4, 6, 7, 8],现在相对所有元素从左到右进行相乘 在「平凡的世界」里,我们这么写: result = 1 for i in [2, 4, 6, 7, 8]: result = result * i print result 返回结果为:2688 用reduce函数,我们这么写: conplus = lambda a,b: a*b print reduce(conplus , [2, 4, 6, 7, 8]) 返回结果为2688.
因此,Reduce函数的使用格式提炼如下:
result = Map(func, [a1, a2, a3...]),将list中元素,从左到右进行func计算,先计算func(a1, a2), 在计算func(func(a1, a2), a3).....
这些函数相互搭配使用,据说(我也不敢肯定)能代替任务的Python程序!不管怎样,我们大概知道了「函数式编程」这个概念:
它用一系列函数取解决问题,代码简洁,没有循环体,也不用生成各种倒来倒去的临时变量。
但是,回到开篇王垠的批判文章,「函数式编程」有哪些缺点?下次有机会再说。
- END -