函数响应式编程(FRP)—基础概念篇
原文出处:http://ios.jobbole.com/86815/、
一函数响应式编程
说到函数响应式编程,就不得不提到函数式编程,他们俩有什么关系呢?今天我们就详细的解析一下他们的关系。
现在下面有4个概念,需要我们理清一下他们之间的关系:
面向对象编程Object Oriented Programming
响应式编程Reactive Programming
函数式编程Functional Programming
函数响应式编程Functional Reactive Programming
我们先来说一说什么是函数式编程Functional Programming,我们先来看看wikipedia上的相关定义:
Functional Programming is a programming paradigm
- treats computation as the evaluation of mathematical functions.
- avoids changing-state and mutable data
总结一下Functional Pragramming具有以下几个特点:
1.函数是“第一等公民”
2.闭包和高阶函数
3.不改变状态(由此延伸出“引用透明”的概念)
4.递归
5.只用”表达式“,不用”语句“,没有副作用
接下来依次说一下这些特点:
一.函数是”第一等公民“
所谓“第一等公民”(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数或者作为别的函数的返回值。
Haskell,OCaml,Standard ML,Scala 和 F# 在内的大量 (函数式) 编程语言都不同程度地借鉴了frist class 的理念。
PS:世界上最纯粹的函数式编程语言非Haskell莫属。
二.闭包和高阶函数
闭包是起函数作用并且可以向对象一样操作的对象。与此类似,函数式编程语言支持高阶函数。高阶函数可以用另一个函数(间接地,用一个表达式)作为其输入参数,在大多数情况下,他甚至可以返回一个函数作为其输出参数。这两种结构结合在一起使用可以用优雅的方式进行模块化编程,这是使用函数式编程的最大好处。
三.不改变状态
不改变状态:
函数式编程只是返回新的值,不修改系统变量。因此,不修改变量,也是他的一个重要特点。在其他类型的语言中,变量往往用来保存状态state,不修改变量,意味着状态不能保存在变量中。函数式编程使用参数保存状态,最好的例子是递归。
避免使用程序状态和可变对象,是降低程序复杂度的有效方法之一,这也是函数式编程的精髓。函数式编程强调执行的结果,而非执行的过程。我们先构建一系列简单却具有一定功能的小函数,然后将这些函数进行组装以实现完整的逻辑和复杂的运算,这是函数式编程的基本思想。
引用透明:
如果提供同样的输入,那么函数总是返回同样的结果。就是说,表达式的值不依赖于可以改变值的全局状态。这使您可以从形式上推断程序的行为,因为表达式的意义值取决于其子表达式而不是计算顺序或者其他表达式的副作用。
面试题: 纯函数式的闭包是否满足函数式编程里面不改变函数状态的特性?
面试题:如何理解引用透明?
四.递归
函数式编程是用递归作为控制流程的机制。
五.只用“表达式”,不用“语句”,没有副作用
表达式expression是一个单纯的运算过程,总是有返回值;语句statement是执行某种操作,没有返回值。函数式编程要求,只是用表达式,不适用语句。也就是说,每一步都是单纯的运算,而且都有返回值。
原因是函数式编程的开发动机,一开始就是为了处理运算somputation,不考虑系统的读写(I/O)。语句属于读写操作,所以就被排斥在外。
函数式编程强调没有”副作用“,意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得改变外部变量的值。
最后再来说说函数响应式编程。
首先函数响应式编程肯定是满足函数式编程的上述特性的。函数响应式编程是面向离散事件流的,在一个时间轴上会产生一些离散事件,这些事件会依次向下传递。
RAC就是Cocoa框架下的函数响应式编程的实现。它提供了基于时间变化的数据流的组合和变化。
接着再来说说之前说的4种编程范式,总结出来,如果按照类似继承图谱来看的话,应该如下图:
首先在声明式编程里面有2大家族,那就是函数式编程和数据流编程,数据流编程下面就是响应式编程,而函数响应式编程是”继承”于函数式编程和响应式编程的。
面向对象编程就属于指令式编程的范畴。从上面2张图来看,我们可以很明显看出这4者是什么关系了。
二.链式调用
定义:f(x),表示的是一种态射,从x的定义域到f(x)值域的态射。如果定义域和值域是完全相同的话,这种映射也成为单元态射。那么满足单元态射的函数,就可以进行链式调用。
以RAC为例,把RACSignal链式传递下去,subscribeNext就会返回一个RACSignal,定义域和值域都是RACSignal,那么就满足了单元态射的要求,就可以链式调用下去。
面试题:组成链式调用的必要条件就是在方法里面返回对象自己
这个说法是错误,举个例子:RAC每次做信号变换的时候,都产生了一个新的信号,所以返回自己就并不是必要条件。其实如果返回自己的同类或者和自己类似的类型,里面也包含可以继续链式调用的方法,也是可以组成链式调用的。
三.关于RAC的其他一些概念
面试题:ReactiveCocoa是Facebook出的一个FRP开源库
错误,是写Github客户端时候的附属品,附带开发出的一个开源框架。
面试题:ReactiveCocoa是基于KVO的一个开源库
错误。KVO是RAC非常次要的部分,甚至可以说没有KVO,RAC依旧可以存在。
面试题:ReactiveCocoa是一个纯函数式编程的库
错误,由于Cocoa框架并不是函数式,RAC又是在Cocoa框架下,所以就不是纯函数式。在命令式编程的语言范畴里面实现纯函数编程,需要折中的方法,我们可以封装命令式编程,使其向上层可以形成纯函数式的,但是下层肯定就是命令式编程实现的。
最后我们再来区分一个概念:
面试题:RAC中Pull-driver和Push-driver的区别?
Pull-driver是指的是任何时刻,我们如果需要数据了,都可以从pull-driver里面拿走数据,因为数据先存储了。整个取数据的时间控制在调用者手上。典型的例子就是for-in循环,这就是一个pull-driver的操作。不管你循环几次,每次循环如何操作,数组或者字典里面的数据都一直存在在那里,“躺”在那里。
Push-driver是相反的,在任何时刻,当有数据或者事件产生,都会push给你,如果你此时没有处理,该事件或者数据就丢失了。整个取数据的时间并不控制在调用者的手里。
Pull-driver可以类比看书,知识和文字不管你看不看,一直都在书里。
Push-driver可以类比看电视,节目不管你看不看,都一直播放,你错过了就是错过了。
在RAC里面,Sequence就是一个pull-driver,Signal就是一个push-driver。
未完待续……
函数响应式编程(FRP)—基础概念篇的更多相关文章
- 函数响应式编程(FRP)从入门到”放弃”——基础概念篇
前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了. 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的 ...
- 函数响应式编程(FRP)框架--ReactiveCocoa
由于工作原因,有段时间没更新博客了,甚是抱歉,只是,从今天開始我又活跃起来了,哈哈,于是决定每周更新一博.大家互相学习.交流. 今天呢.讨论一下关于ReactiveCocoa,这个採用函数响应式编程( ...
- 函数响应式编程(FRP)思想-Callback风格
序 ReactiveCocoa是IOS广为使用的技术框架,而ReactiveCocoa的核心思想就FRP.FRP不同于JAVA的object-oriented和AOP,FRP能让你的代码像数学一样简洁 ...
- 函数响应式编程及ReactiveObjC学习笔记 (-)
最近无意间看到一个视频讲的ReactiveObjC, 觉得挺好用的 但听完后只是了解个大概. 在网上找了些文章, 有的写的比较易懂但看完还是没觉得自己能比较好的使用RAC, 有的甚至让我看不下去 这两 ...
- RxJS入门之函数响应式编程
一.函数式编程 1.声明式(Declarativ) 和声明式相对应的编程⽅式叫做命令式编程(ImperativeProgramming),命令式编程也是最常见的⼀种编程⽅式. //命令式编程: fun ...
- ReactiveCocoa,最受欢迎的iOS函数响应式编程库(2.5版),没有之一!
简介 项目主页: ReactiveCocoa 实例下载: https://github.com/ios122/ios122 简评: 最受欢迎,最有价值的iOS响应式编程库,没有之一!iOS MVVM模 ...
- Win32多线程编程(1) — 基础概念篇
内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API.当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Serv ...
- 函数响应式编程RxJava
RxJava 到底是什么 一个词:异步. RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and event- ...
- RxSwift 函数响应式编程
Max 在 Boston 上学,在 San Francisco 工作,是一名软件工程师及创业者.当他还在高中的时候就在一家创业公司工作了,他非常喜欢使用 iOS.Android 以及 JavaScri ...
随机推荐
- RxJava 的使用入门
一.什么是 RxJava? RxJava 是一个响应式编程框架,采用观察者设计模式.所以自然少不了 Observable 和 Subscriber 这两个东东了. RxJava 是一个开源项目,地址: ...
- Android拓展系列(11)--打造Windows下便携的Android源码阅读环境
因为EXT和NTFS格式的差异,我一直对于windows下阅读Android源码感到不满. 前几天,想把最新的android5.0的源码下下来研究一下,而平时日常使用的又是windows环境,于是专门 ...
- 分享Kali Linux 2016.2第43周镜像
分享Kali Linux 2016.2第43周镜像Kali Linux官方于10月23日如约发布了2016.2第43周镜像.和以往一样,此次镜像包含了11个镜像文件,包含PC端的32和64位镜像,还有 ...
- blade快速使用指南
一.简介模板引擎 模板引擎是将网站的页面设计和PHP应用程序几乎完全分离的一种解决方案,它能让前端工程师专注页面搭建,让后台工程师专注功能实现,以便实现逻辑分离,让每个人发挥所长.模板引擎技术的核心是 ...
- wpf Popup Win8.0 bug HorizontalOffset 弹出位置偏移
问题描述参考 wpf 客户端[JDAgent桌面助手]开发详解(四) popup控件的win8.0的bug 当开发完程序后,我们在多操作系统测试时候发现:win8.0 系统中 popup 弹出的位置 ...
- Codeforces 687C The Values You Can Make(DP)
题目大概说给n个各有价值的硬币,要从它们中选出若干个组合成面值k,而要求的是各个方案里这些选出的硬币能组合出来的面值有哪些. 有点绕.. dp[i][j][k]表示前i个硬币中 能否 组合成面值j且选 ...
- git冲突解决
http://www.cnblogs.com/sinojelly/archive/2011/08/07/2130172.html http://hi.baidu.com/jqxw4444/item/f ...
- SIFT特征提取分析
SIFT特征提取分析 sift 关键点,关键点检测 读'D. G. Lowe. Distinctive Image Features from Scale-Invariant Keypoints[J] ...
- 【Excel】Excel根据单元格背景色求和
例:用公式计算单元格背景色为浅蓝色的数字之和 步骤一: Office 2003 Insert->Name->Define,Names in workbook输入getColor或ge ...
- Air Raid[HDU1151]
Air RaidTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...