zoukankan      html  css  js  c++  java
  • 函数式编程

    函数式编程

    函数式编程(Functional Programming)之前都只是听说过,没有使用过所谓的函数式编程思想。不大理解这个概念。最近弄python的时候遇到了这个概念。

    函数式编程对应的是命令式编程(imperative programming)。我们平时写的程序大都属于这种编程方式:如果a大于b,就执行这个操作,否则的话,就执行这样的操作。我们一直研究的面向对象的编程也便是属于命令式编程的一种。

    函数式编程最重要的是一切都是函数。这里的一切包括什么?函数可以是变量么?可以。函数可以是返回值么?可以。

    高阶函数

    如果函数是变量,那么这个把函数当作变量的函数就是高阶函数。比如python中的这个函数:

    #!/usr/bin/python
    #coding:utf-8
    
    def g(f, a, b):
        return f(a, b)
    
    def add(a, b):
        return a + b
    
    val = g(add, 1, 2)
    print val
    

    其中g这个函数它就是高阶函数,他有一个参数为f。

    在python中,高阶函数的代表就是map和reduce。比如可以看下下面的例子:

    #!/usr/bin/python
    #coding:utf-8
    
    def f(a):
        return a * a
    
    def add(a, b):
        return a + b
    
    val1 = map(f, [1,2])
    val2 = reduce(add, val1)
    print val2
    
    

    在上面例子里面,map和reduce都是高阶函数,它们的第一个参数传递进去的是函数。但是当然上面的例子写的有点low,一点都不python,一般来说,我们使用匿名函数lambda来替换传递进来的参数。

    #!/usr/bin/python
    #coding:utf-8
    
    val1 = map(lambda x: x*x, [1,2])
    val2 = reduce(lambda x,y: x+y, val1)
    print val2
    
    

    这里引申的匿名函数的意思就很明显了。它就是函数的扩展。

    闭包

    高阶函数除了可以接受函数作为参数之外,还可以把函数作为返回值返回。

    #!/usr/bin/python
    #coding:utf-8
    
    def multi(a, b):
        def f():
            return a * a + b * b
        return f
    
    val = multi(1, 2)
    print val()
    
    

    把函数作为返回值,上面的例子在multi的时候其实并没有执行对应的计算,而是在print的时候才执行计算,这个是一种延迟行为。我们称之为惰性求职(lazy evaluation)。

    我们看到,在multi函数定义的a和b这两个局部变量,并不随着multi调用而销毁,在print这行,才具体执行的时候,a=1和b=2 还继续存在着。这就是“闭包”的威力。

    函数式编程

    回归到函数式编程,虽然说函数式编程是一种思维,和语言无关。但是只有实现了上述匿名函数,函数闭包等功能的语言才有函数式编程的能力。它最本质的观点是,所有的编程思想都是以函数为基本思想。

    首先,函数式编程认为每个函数都是封闭的,不依赖外部的数据,也不改变外部的数据。比如我们常用的OO里面的方法,函数式编程就觉得不合理。

    class A {
        public $isAuth = true;
    
        public isAuth(){
            return $this->isAuth;
        }
    }
    

    这里面的isAuth依赖外部的变量$isAuth,所以它是不符合函数式编程的函数封闭原理的。

    其次,函数像变量一样使用,这一点我们上面的部分已经说明清楚了。经常说的一句话是,函数是一等公民。

    比如像很多算法里面使用的递归算法,就算是函数式思维和非函数式思维的区别。比如计算斐波那契数列,从函数式思维开始思考,我们很容易思考到递归算法。而从其它思维出发,我们常常考虑的就是非递归解法。

    public static long fib(int n)
    {
      if(n <= 1)
         return n;
      else
          return fib(n-1) + fib(n-2);
    }
    

    从这个例子我们可以看出,使用函数式思想的一个好处,非常符合我们人类直观的理解。我们是要告诉程序要去做什么,而不是怎么去做。

    参考

    http://yangcongchufang.com/高级python编程基础/python-functional.html#dir2

    https://www.zhihu.com/question/28292740

    https://www.ibm.com/developerworks/cn/linux/l-cn-closure/index.html

    http://coolshell.cn/articles/10822.html

  • 相关阅读:
    Golang (Go语言) Mac OS X下环境搭建 环境变量配置 开发工具配置 Sublime Text 2
    网站状态保存方法
    学习MVC第一课:初识MVC
    ASP.NET MVC 中动态从路由中获取URL
    ASP.NET MVC2程序开发入门到精通系列课程01
    OpenCV 里的sigma 是多少
    日期大小比较
    安装完ODAC,出现ORA12560:TNS:协议适配器错误
    Spring+IBATIS+Struts2开发流程
    【转】SSH标准配置
  • 原文地址:https://www.cnblogs.com/yjf512/p/7240466.html
Copyright © 2011-2022 走看看