什么是函数式编程思维(到底什么是函数式编程思维)

文章目录:

  1. 什么是函数式编程思维
  2. 到底什么是函数式编程思维
  3. 学习函数式编程的推荐书籍?

一、什么是函数式编程思维

按照百度百科,据说函数式编程是计算机把运算当做函数处理。我本人用过一年左右Haskell(一种函数式编程语言),感觉有这些特点:

1 支持lamda表达式运算(lamda表达式的特点是替代运算,比如λx.xx的含义是属于输入x,结果是xx,如果有一个表达式为(λx.xx)y,函数是(λx.xx),输入是y,则结果是yy。

2 写不了循环,都用递归弄。

3 没有办法直接改全局变量,你只能把修改全局变量的函数传进函数操作(如果你有n个全局变量在一个函数中使用,在haskell中你要穿长度为n的数据量,这使得代码冗余,不过也保障了线程安全)。

4 高阶函数让一切变得方便,你可以把函数当做参数传入高阶函数(比如fmap,map,zip,fold等等),然后把传入的函数应用到传入的数据结构里,有点像C的函数指针。比如map可以把(a->b,输入a类型数据返回b类型数据)类型函数作用于整个数据类型为a的数组,map函数吧a->b类型函数作用于a类型数组中的每一项,然后返回类型为b的结果集。

5 对泛型的支持友好,你可以同时在函数声明中定义a类型b类型,数据类型安全有保障。更有甚者,在另外一个函数式编程语言idris中,数据类型(比如int)可以当成数据使用(这是很多程序语言都没有的)。

6 就Haskell而言,数据类型定义很灵活,对于除法,你可以用haskell自带的maybe类型(比如maybe double)作为返回类型,如果是有效值a就返回(Just a),如果是除0,你可以让结果返回Nothing。

7 Haskell中有一类东西叫type class,和Java里面的抽象类或者接口很像。如果你有数据类型a,b实现了一种type class(叫他class)的所有函数, 你可以把class里面定义的抽象函数用于a,b。这是多态的支持。如果你学得足够高深,函数式编程里面的Monad,Arrows等type class将会是你的常用技巧。

8 惰性求值。你可以定义一个无限长自然数表。如果你直接打印它,电脑尽其所能从0,1,2开始输出到内存溢出或者系统自己停止为止。如果你用了take函数,你可以之选择取前面5个值。此时电脑只生成0到4的表,因为从5开始数据没有用了。这可以大幅提升运行速度。

我说的这些都是在去年一年对函数式编程学习的小总结。需要学习的话,你可以上Hoogle(这不是google,一个haskell的官方API网站)查你不会的函数。

二、到底什么是函数式编程思维

形而上的思维:

1、数据不可变的思维:let a = 100,意义不是把100赋值给变量a,而是把a符号绑定(或者叫匹配)到100。

2、一切皆表达式思维:if b then 100 else 10,这不是条件跳转,而是一个三元表达式。

3、函数是之一类值:函数可以作为参数传输,也可以作为结果返回,更可以由一个函数演化成另一个函数。

形而下的思维:

1、用递归替换循环。

2、难以尾递归的时候考虑使用延续函数(continuation)。

3、高阶函数、部分应用、Lambda演算。

4、用泛型、接口、可区别联合类型替换类继承。

5、用二叉树替换普通链表后可以支持高并发计算。

===================================================

这些也只是feature而不是思维。我想知道的是这些feature之后的逻辑。

-----------------------------------------------------------------------------------------------------

再往上说就不接地气了,先从函数式语言说起,函数式语言其实就是模仿人的数学思维而发明的朴素,后来因为离机器太远,不容易优化而被诟病。但科技发展到今天,编译器的优化能力已经很强,软件系统越来越复杂,人的分工越来越细,函数式语言离数学更近,离机器更远,反而成为一种优势,有助于人把问题清晰化。从这个层面看,函数式编程是一种什么思维,就是推离机器的数学思维。这里没有内存、寄存器的想法,在 a=1之后,a 就不可能再等于2,当然你可以在 let a = 1 之后,再 let a = 2,但是这个a 就已经不是那个a,在停留在有内存概念的编程世界里,a 一直是 a,它是装东西的桶或者盒子,只是每次里面装的东西不同。

那么,总的来说,是先有朴素的函数式语言,然后才有今天发现函数式编程的好处, 启用了函数式语言的某些 feature,目的是为了把问题解构成更小的粒度。所以这些feature背后没什么逻辑,就好像问这石头为什么长这样一样。我只能打句偈语:本来就这样。

三、学习函数式编程的推荐书籍?

1、关于书籍的选择

1)、选择好学习的函数式编程语言后,可以根据自己的情况去一些书店、网上商城(比京东、当当)选择相应编程语言的书籍资料。

2)、如果从思想入手,并且希望学的更深入,个人建议从SICP(《计算机程序的构造和解释》)入手,Scheme语言是思想的锤炼。

3)、如果用户是java程序员,建议看看clojure,这是个极具生产力的语言工具,它运行于java平台上的lisp。twitter的storm就是用它写的。clojure现在已经是黑客领域最耀眼的明星了。最重要的是clojure已经出版了很多本中文教材,可以入手学习了。顺带加上SICP可以加快学习进度。以项目为中心可以选择《Clojure经典实例 功能性编程全面指南》、没有基础的可以选择《Living Clojure》(中文版)、老程序员可以参考《Clojure编程乐趣》中文版 。

4)、如果不为作项目,只是为了提升个人的能力或者编程思想,可以选择haskell语言,这个资料也比较多,无论书籍还是视频、文档等等 。

2、简单说,"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。

它属于"结构化编程"的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。举例来说,现在有这样一个数学表达式:

  (1 + 2) * 3 - 4
传统的过程式编程,可能这样写:

  var a = 1 + 2;

  var b = a * 3;

  var c = b - 4;

函数式编程要求使用函数,我们可以把运算过程定义为不同的函数,然后写成下面这样:

  var result = subtract(multiply(add(1,2), 3), 4);
这就是函数式编程。

3、函数编程的特点:

函数式编程具有五个鲜明的特点。

1)、 函数是"之一等公民"

所谓"之一等公民"(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。

举例来说,下面代码中的print变量就是一个函数,可以作为另一个函数的参数。

  var print = function(i){ console.log(i);};

  [1,2,3].forEach(print);

2)、只用"表达式",不用"语句"

"表达式"(expression)是一个单纯的运算过程,总是有返回值;"语句"(statement)是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。

原因是函数式编程的开发动机,一开始就是为了处理运算(computation),不考虑系统的读写(I/O)。"语句"属于对系统的读写操作,所以就被排斥在外。

当然,实际应用中,不做I/O是不可能的。因此,编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。

3)、没有"副作用"

所谓"副作用"(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。

函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

4)、不修改状态

上一点已经提到,函数式编程只是返回新的值,不修改系统变量。因此,不修改变量,也是它的一个重要特点。

在其他类型的语言中,变量往往用来保存"状态"(state)。不修改变量,意味着状态不能保存在变量中。函数式编程使用参数保存状态,最好的例子就是递归。下面的代码是一个将字符串逆序排列的函数,它演示了不同的参数如何决定了运算所处的"状态"。

  function reverse(string) {

    if(string.length == 0) {

      return string;

    } else {

      return reverse(string.substring(1, string.length)) + string.substring(0, 1);

    }

  }

由于使用了递归,函数式语言的运行速度比较慢,这是它长期不能在业界推广的主要原因。

5)、引用透明

引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。

有了前面的第三点和第四点,这点是很显然的。其他类型的语言,函数的返回值往往与系统状态有关,不同的状态之下,返回值是不一样的。这就叫"引用不透明",很不利于观察和理解程序的行为。

到此,以上就是小编对于函数式编程思维 mobi的问题就介绍到这了,希望介绍关于函数式编程思维 mobi的3点解答对大家有用。

mobi图书网
mobi图书网管理员

上一篇:哈利波特小说全集 *** (优质kindle电子书资源分享)
下一篇:金庸小说全集 *** (优质kindle电子书资源分享)

留言评论

暂无留言