美文网首页函数式编程程序员Android知识
函数式编程思维第一章为什么

函数式编程思维第一章为什么

作者: 每天学点编程 | 来源:发表于2017-09-24 10:49 被阅读76次

    请关注我的微信公众号


    个人微信公众号

    技术交流群 (仅作技术交流):642646237
    请关注我的头条号:


    学习编程范式的困难

    学习一种全新的编程范式,困难并不在于掌握新的语言。语法不过是些小细节罢了。真正考验人的,是怎么学会用另一种方式去思考。
    用“函数式”的方式编写代码牵涉到诸多方面,包括设计上的种种取舍、不同重用单元的作用等。比起语法,更看重思路。

    所有的语言都趋向函数式

    所有的语言都日渐向函数式靠拢。

    范式转变

    计算机科学的进步经常是间歇式的,好思路有时搁置数十年后才突然间变成主流。
    第一种面向对象的语言Simula 67是1967年发明的,可是直到1983年诞生的C++终于流行起来以后,面向对象才真正成为主流。
    再优秀的想法也得等待技术基础慢慢成熟。早年Java总被认为太慢,内存耗费太高,不适合高性能的应用,如今硬件市场的变迁把它变成了极具吸引力的选择。

    函数式编程的发展轨迹与面向对象编程十分相似,它也是诞生在学院里。

    举例说明命令式和函数式的区别——词频统计

    java8之前的版本:


    对于提倡以步进方式处理集合(正则表达式的匹配结果)遍历的语言来说,这是司空见惯的编码风格。
    在一个迭代块里完成三项操作,这是牺牲了代码的清晰来换取执行性能。

    Java 8版本:

    命令式编程风格迫使我们出于性能考虑,把不同的任务交织起来,以便能够用一次循环来完成多个任务。而函数式编程用map()filter()这些高阶函数把我们解放出来,让我们站在更高的抽象层次上去考虑问题,把问题看得更清楚。

    跟上语言发展的潮流

    所有的主流语言都在进行函数式方面的扩充。

    把控制权让渡给语言/运行时

    自动垃圾收集
    人生苦短,远离malloc。
    把乏味单调的任务托付给语言和运行时。
    Java接管内存分配减轻了我们的负担,函数式编程语言让我们用高阶抽象从容取代基本的控制结构,也有着同样的意义。
    将琐碎的细节交托给运行时,令繁冗的实现化作轻巧。

    简洁

    函数式抽象和面向对象抽象的关键区别:面向对象编程通过封装不确定因素来使代码能被人理解;函数式编程通过尽量减少不确定因素来使代码能被人理解。

    精细地控制谁能够感知状态和改变状态——“不确定因素”(moving parts)

    与其建立种种机制来控制可变的状态,不如尽可能消灭可变的状态这个不确定因素。其立论的根据是这样的:假如语言不对外暴露那么多有出错可能的特性,那么开发者就不那么容易犯错。

    在面向对象的命令式编程语言里面,重用的单元是类和类之间沟通用的消息,这些都可以用类图(class diagram)来表述。
    OOP的世界提倡开发者针对具体问题建立专门的数据结构,相关的专门操作以“方法”的形式附加在数据结构上。

    函数式语言提倡在有限的几种关键数据结构(如list、set、map)上运用针对这些数据结构高度优化过的操作,以此构成基本的运转机构。开发者再根据具体用途,插入自己的数据结构和高阶函数去调整机构的运转方式。

    比起一味创建新的类结构体系,把封装的单元降低到函数级别,更有利于达到细粒度的、基础层面的重用。

    函数式程序员喜欢用少数几个核心数据结构,围绕它们去建立一套充分优化的运转机构。面向对象程序员喜欢不断地创建新的数据结构和附属的操作,因为压倒一切的面向对象编程范式就是建立新的类和类间的消息。把所有的数据结构都封装成类,一方面压制了方法层面的重用,另一方面鼓励了大粒度的框架式的重用。函数式编程的程序构造更方便我们在比较细小的层面上重用代码。

    举例说明——Java版本


    indexOfAny()方法的参数是一个CharSequence和一个数组,它会在CharSequence中查找数组里的字符,并返回任意一个字符第一次出现的索引位置。

    对于searchChars中的任意字符,在目标字符串中查找该字符第一处匹配的索引位置。

    举例说明——Scala版本

    Scala的zip()方法将(从0到输入字符串长度值的)数字集合与String对象中所含字符的集合对位结合,组成一个新的、由数字和字符对构成的集合。

    zip方法得名于它像拉链(zipper)一样让两个集合对齐咬合在一起。

    null的存在是Java语言的一大混乱来源:它到底是一个有效的返回值,还是表明返回值缺失了?包括Scala在内的很多函数式语言通过Option类来避免这种语义上的含混,其取值要么是表示没有返回值的None,要么是容纳了返回值的Some

    scala版本的程序可以直接修改为返回匹配项的一个缓求值列表:


    相关文章

      网友评论

        本文标题:函数式编程思维第一章为什么

        本文链接:https://www.haomeiwen.com/subject/izjmjxtx.html