原文出处: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 ...
随机推荐
-
[WCF]缺少一行代码引发的血案
这是今天作项目支持的发现的一个关于WCF的问题,虽然最终我只是添加了一行代码就解决了这个问题,但是整个纠错过程是痛苦的,甚至最终发现这个问题都具有偶然性.具体来说,这是一个关于如何自动为服务接口(契约 ...
-
[moka同学笔记]Yii下国家省市三级联动
第一次做省市三级联动时候遇到了坑,感觉还是自己太菜.头疼了很久研究了很久,最后终于发现了问题.大致总结一下思路 在控制器中实例化model,然后在视图中渲染所有国家,当选取国家时候,ajax通过 id ...
-
AJAX,JSON用户名校验
效果 开发结构 1,src部分有两个包dao和servlet 1.1dao包下有两个数据库工具类文件 SqlHelper.java package org.guangsoft.dao; import ...
-
MONO常用快捷键
Action Mac OS X Win/Linux 注释代码(//) Cmd + / Ctrl + / 注释代码(/**/) Cmd + Option + / Ctrl + Shift + / 格 ...
-
使用ArrayList对大小写字母的随机打印
从a~z以及A~Z随机生成一个字母并打印:打印全部的字母 package com.liaojianya.chapter1; import java.util.ArrayList; /** * This ...
-
Pen Editor
Pen Editor
-
poj 2965
http://poj.org/problem?id=2965 本题要结合poj 1753 来看最好...又有了一点搜索的经验..加油... #include <iostream> #inc ...
-
.NET中lock的使用方法及注意事项
lock就是把一段代码定义为临界区,所谓临界区就是同一时刻只能有一个线程来操作临界区的代码,当一个线程位于代码的临界区时,另一个线程不能进入临界区,如果试图进入临界区,则只能一直等待(即被阻止),直到 ...
-
KoaHub.js:使用ES6/7特性开发Node.js框架
KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Function, Class, Async & ...
-
ASP.NET Core 一步步搭建个人网站(7)_Linux系统移植
摘要 考虑我们为什么要选择.NET Core? 因为它面向的是高性能服务器开发,抛却了 AspNet 的臃肿组件,非常轻量,加上微软的跨平台战略,对 Docker 的亲和性,对于开发人员也非常友好,所 ...