1. 什么是函数式编程?

函数式编程是阿隆佐思想的在现实世界中的实现, 它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及异变物件。 函数式编程的最重要基础是λ演算。而且λ演算的函數可以接受函數當作輸入(引數)和輸出(傳出值),函數式編程更加強調程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程。函数式编程的杀手锏正是当今世界上日益增长的并行性编程和元数据编程趋势。其主要思想就是把运算过程尽量写成一系列嵌套的函数调用

2. 函数式编程的特点:

  • 函数是“第一等公民”:函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值
  • 只用“表达式”,不用语句:“表达式”--是一个单纯的运算过程,总是有返回值; ‘语句’--执行某种操作,没有返回值。函数式编程要求,只用表达式,不使用语句,也就是说,每一步都是单纯的运算,而且没有返回值。但在实际的I/O是不可能的,因此,编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。
  • 没有副作用:函数要保持独立,所有的功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值
  • 不修改状态: 函数式编程只是返回新的值,不修改系统变量。
  • 引用透明: 函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的

3.入手一门新的语言的 时候,一般关注的内容有:
1.原生的数据结构
2.运算符
3.分支控制
4.如果是面向对象的编程语言,其面向对象的实现是怎样的
5.如果是函数式编程语言,其面向函数式编程的实现是怎么样的
6.如果是面向接口的编程语言,器面向接口是如何实现的
7.如果是支持泛型编程,那么又是如何实现的
 
 
4.对于支持函数式编程的语言,其一般的特点可能包含以下几种:
1. 支持递归
2. 函数本身是语言First Class 的组成要素,且支持高阶函数和闭包
3. 函数调用尽可能没有副作用(Side Effect)的条件 
    前面的1、2 swift是毋庸置疑的。对于条件3:
    为了减少函数的副作用,很多函数式编程语言都力求达到所谓的“纯函数”。纯函数是指函数与外界交换数据的唯一渠道是参数和返回值,而不会受到外部变         量的干扰。这似乎是跟闭包的概念相抵触。因为闭包本身的一个重要的特点就是可以访问到函数定义时的上下文环境。因为闭包本身的一个重要的特点就是可以       访问到函数定义时的上下文环境。
           事实上,为了支持这种情况下的纯函数,一些编程语言提供的数据结构式不可变的(Persist)。比如说,在 Python 中,字符串str就是一类不可变的数据       结构。 你不能在原来的字符串上进行修改,每次想要进行类似的操作,其实都是生成了一个新的str对象。 然而 Python 中的链表结构则是可变的。

a = "hello ,"
b = a
a += 'world'
print a # hello ,world
print b # hello ,

    swift中更多的是值类型,而不是引用类型,你会发现Int,Float,String,Array,Dictionary等都是Struct类型,而Struct都是值类型【暗示了结构体应该主要         用于封装数据】,当然Enum也是值类型

在swift中区分值类型和引用类型是为了将可变和不可不区分开来。值类型的数据传递给函数,函数内部可以自由拷贝,改变值,而不用担心产生副作用。在多线      程环境下,多个线程同时运行,可能会意外错误地修改数据,这常常会是一种难以调试的bug。而使用值类型,你可以安全地在线程间传递数据,因为值类型传递      是拷贝,所以无需在线程间同步数据变化。这就可以保证代码线程环境下的安全性。

swift中的参数定义中加入inout,这样的话就可以通过参数来修改变量。这个特性很有C的风格。

使用swift自带的数据结构并不能很好的的实现“无副作用”的“纯函数式”编程。幸好作为一种关注度很高的语言, 已经有开发者为其实现了一套完全满足不可变要      求的数据结构和库:Swiftz。坚持使用let和swiftz提供的数据结构来操作,就可以实现“纯函数式”编程。

不变性有诸多好处

  • 更高层次的抽象。程序员可以以更接近数学的方式思考问题。

  • 更容易理解的代码。由于不存在副作用,无论多少次执行,相同的输入就意味着相同的输出。纯函数比有可变状态的函数和对象理解起来要容易简单得多。你无需再担心对象的某个状态的改变,会对它的某个行为(函数)产生影响。

  • 线程安全的代码。这意味着多线程环境下,运行代码没有同步问题。它们也不可能因为异常的发生而处于无法预测的状态中。

惰性求值

惰性计算是函数式编程语言的一个特性。惰性计算的表达式不在它被绑定到变量之后就立即求值,而是在该值被取用的时候求值。惰性计算有如下优点。

  • 首先,你可以用它们来创建无限序列这样一种数据类型。因为直到需要时才会计算值,这样就可以使用惰性集合模拟无限序列。
  • 第二,减少了存储空间。因为在真正需要时才会发生计算。所以,节约了不必要的存储空间。
  • 第三,减少计算量,产生更高效的代码。因为在真正需要时才会发生计算。所以,节约那部分没有使用到的值的计算时间。例如,寻找数组中第一个符合某个条件的值。找到了之后,数组里该值之后的值都可以不必计算了。
func doSomeWork(optional:Int?,defaultValue:Int)->Int{
if let opt = optional{
return opt
}else{
return defaultValue
}
} func doSomeWorkNew(optional:Int?, defaultValue:()->Int)->Int{ if let opt = optional{
return opt
}else{
return defaultValue()
}
} let value:Int? = 1
doSomeWork(value, (2+5))
doSomeWorkNew(value, { () -> Int in
return 2+5
})

上面的代码可以感觉到惰性求值的好处。

swift也提供了支持惰性求值的语法:下面展示了将默认是严格求值的数组变为惰性序列:

let r = 1...3
let seq = lazy(r).map {
(i: Int) -> Int in
println("mapping \(i)")
return i * 2
} for i in seq {
println(i)
}

 

Swift对函数式编程的支持,使得程序员多了一种选择。Swift并不强迫程序员一定要以面向对象的方法思维。在场景合适的情况下,程序员可以选择使用函数式风格编写代码。如果确实是合适的场景,就能够改善生产力。现实的选择是支持面向对象编程的同时,提供函数式的支持。这样,在大部分面向对象游刃有余的地方,仍然可以使用面向对象的方法。而在适合函数式编程的地方,而你又拥有函数式编程的思维和能力时,还可以采用函数式的编程方法改善生产力。

接下来的系列文章中我将以《Functional Programing in Swift》这本书,来一起学习swift的函数式编程。

 

swift 之函数式编程(一)的更多相关文章

  1. swift之函数式编程

    函数式编程初探 最近初学swift,和OC比,发现语言更现代,也有了更多的特性.如何写好swift代码,也许,熟练使用新特性写出更优秀的代码,就是答案.今天先从大的方向谈谈swift中的编程范式-函数 ...

  2. swift之函数式编程(四)

    文章内容来自<Functional Programing in Swift>,具体内容请到书中查阅 Map, Filter, Reduce Functions that take func ...

  3. swift之函数式编程(二)

    本文的主要内容来自<Functional Programming in Swift>这本书,有点所谓的观后总结 在本书的Introduction章中: we will try to foc ...

  4. 最通俗易懂的方式让你理解 Swift 的函数式编程

    函数式编程(Functional Programming)是相对于我们常用的面向对象和面向过程编程的另外一种开发思维方式,它更加强调以函数为中心.善用函数式编程思路,可以对我们的开发工作有很大的帮助和 ...

  5. swift之函数式编程(三)

    文章来源于<Functional Programing in Swift>,本系列仅仅是观后概括的一些内容 Wrapping Core Image 上一篇文章我们介绍了 高阶函数并且展示了 ...

  6. swift之函数式编程(五)

    文章内容来源于<Functional Programing in Swift>,详情请看原著 The Value of Immutability swift 对于控制值改变有一些机制.在这 ...

  7. Swift の 函数式编程

    Swift 相比原先的 Objective-C 最重要的优点之一,就是对函数式编程提供了更好的支持. Swift 提供了更多的语法糖和一些新特性来增强函数式编程的能力,本文就在这方面进行一些讨论. S ...

  8. swift语言的特征:类型系统与函数式编程:swift是面向类型和面向函数编程的语言

    swift语言的特征: 类型系统:值类型与引用类型.泛型.协议类型 函数式编程:

  9. 函数式编程-将Monad(单子)融入Swift

    前言 近期又开始折腾起Haskell,掉进这个深坑恐怕很难再爬上来了.在不断深入了解Haskell的各种概念以及使用它们去解决实际问题的时候,我会试想着将这些概念移植到Swift中.函数式编程范式的很 ...

随机推荐

  1. jmeter JDBC请求连接测试mysql数据库

    所有jmeter基本组件功能本文不做介绍.jmeter要链接mysql数据库,首先得下载mysql jdbc驱动包(注:驱动包的版本一定要与你数据库的版本匹配,驱动版本低于mysql版本有可能会导致连 ...

  2. Tomcat代码执行漏洞(CVE-2017-12615)的演绎及个人bypass

    0x00 漏洞简介 2017年9月19日,Apache Tomcat官方确认并修复了两个高危漏洞. 漏洞CVE编号:CVE-2017-12615和CVE-2017-12616. 其中 远程代码执行漏洞 ...

  3. border-radius:50%和100%究竟有什么区别

    之前写css圆形时总是直接设置border-radius为50%.后来看某css动画网站时发现作者都是用的100%.遂去了解了一下2者的差别. border-radius的值是百分比的话,就相当于盒子 ...

  4. CentOS7下安装MariaDB

    环境:Window10 上建立 VMWare 虚拟机,EasyInstaller 方式安装 CentOS 7 1. “失败”的经历 备份原 repo 文件,并更改 yum 源(方法详见修改yum源)为 ...

  5. unable to dequeue a cell with identifier MealTableViewCell

    1 问题描述 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable ...

  6. 【Kafka】操作命令

    生产者 ./kafka-console-producer.sh --broker-list --topic norm 消费者 ./kafka-console-consumer.sh --zookeep ...

  7. Django内置的用户认证

    认证登陆 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中: 如果用户存在于数据库中,然后再验证用户输入的密码,这样一来就要自己编写大量的代码. ...

  8. SUM游戏

    题意:就是有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取.每次玩家只能从左端或者右端取任意数量个数,但不能两端都取. 所有数都被取走后游戏结束,然后统计每个人取走的所有数之和,作为各自的得 ...

  9. ssh项目访问路径及url请求书写

    在ssh项目中配置好Struts后,一般可以采用两种方式进行后台请求: 1.html形式,包括a标签,form表单,ajax等.此时的访问链接必须写全路径,可以是相对路径,也可以是绝对路径 相对路径方 ...

  10. Docker 最常用的监控方案 - 每天5分钟玩转 Docker 容器技术(78)

    当 Docker 部署规模逐步变大后,可视化监控容器环境的性能和健康状态将会变得越来越重要. 在本章中,我们将讨论几个目前比较常用的容器监控工具和方案,为大家构建自己的监控系统提供参考. 首先我们会讨 ...