原文出处: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

  1. treats computation as the evaluation of mathematical functions.
  2. 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)—基础概念篇的更多相关文章

  1. 函数响应式编程(FRP)从入门到”放弃”——基础概念篇

    前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了. 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的 ...

  2. 函数响应式编程(FRP)框架--ReactiveCocoa

    由于工作原因,有段时间没更新博客了,甚是抱歉,只是,从今天開始我又活跃起来了,哈哈,于是决定每周更新一博.大家互相学习.交流. 今天呢.讨论一下关于ReactiveCocoa,这个採用函数响应式编程( ...

  3. 函数响应式编程(FRP)思想-Callback风格

    序 ReactiveCocoa是IOS广为使用的技术框架,而ReactiveCocoa的核心思想就FRP.FRP不同于JAVA的object-oriented和AOP,FRP能让你的代码像数学一样简洁 ...

  4. 函数响应式编程及ReactiveObjC学习笔记 (-)

    最近无意间看到一个视频讲的ReactiveObjC, 觉得挺好用的 但听完后只是了解个大概. 在网上找了些文章, 有的写的比较易懂但看完还是没觉得自己能比较好的使用RAC, 有的甚至让我看不下去 这两 ...

  5. RxJS入门之函数响应式编程

    一.函数式编程 1.声明式(Declarativ) 和声明式相对应的编程⽅式叫做命令式编程(ImperativeProgramming),命令式编程也是最常见的⼀种编程⽅式. //命令式编程: fun ...

  6. ReactiveCocoa,最受欢迎的iOS函数响应式编程库(2.5版),没有之一!

    简介 项目主页: ReactiveCocoa 实例下载: https://github.com/ios122/ios122 简评: 最受欢迎,最有价值的iOS响应式编程库,没有之一!iOS MVVM模 ...

  7. Win32多线程编程(1) — 基础概念篇

      内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API.当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Serv ...

  8. 函数响应式编程RxJava

    RxJava 到底是什么 一个词:异步. RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and event- ...

  9. RxSwift 函数响应式编程

    Max 在 Boston 上学,在 San Francisco 工作,是一名软件工程师及创业者.当他还在高中的时候就在一家创业公司工作了,他非常喜欢使用 iOS.Android 以及 JavaScri ...

随机推荐

  1. error: bad symbolic reference. A signature in HiveContext.class refers to term hive

    在spark-shell中执行val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc)报错: error: bad symbolic ...

  2. LR连接oracle时出现:SQLState=28000[Oracle][ODBC][Ora]ORA-01017:invalid username/password;logon denied

    出现的现象:

  3. Android利用Fiddler进行网络数据抓包

    最新最准确内容建议直接访问原文:Android利用Fiddler进行网络数据抓包 主要介绍Android及IPhone手机上如何进行网络数据抓包,比如我们想抓某个应用(微博.微信.墨迹天气)的网络通信 ...

  4. 判断App是否在后台运行

    在一些场景中,经常会需要判断App是否在后台运行,比如是否显示解锁界面,收到新消息是否显示Notification等.需求可能是多样化的,但所依仗的原理是相通的,今天Stay打算说说这些需求的最优解. ...

  5. opacity与rgba

    background: rgba(255,255,255,0.6);容器本身透明度变化,它包含的子容器的透明度不变. opacity:0.6;容器及容器包含的子容器的透明度都会发生变化.

  6. js整理2

    字符串 类型 var a = "abc"; var b = new String( a ); var c = Object( a ); typeof a; // "str ...

  7. wpf中手风琴控件Accordion编辑模板后控件不正常。

    昨天有个网友Accordion控件从sl迁移到wpf时候显示不正常.也是就没有效果. 我也是sl做的比较多,wpf玩的少,Accordion模板里触发器,状态组调了一早上都没达到满意效果, 无奈只有百 ...

  8. SqlServer事务回滚(2)

    SQL Server 2008中SQL应用系列--目录索引 SQL事务 一.事务概念    事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行.因此事务是 ...

  9. HDU-2844 Coins(多重背包)

    Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...

  10. 【原】iOS学习之XMPP环境搭建

    XMPP环境搭建 1> 搭建XMPP环境需要几个辅助工具: Java Openfire 采用Java开发,因此我们需要先安装Java环境 XAMPP XAMPP(Apache+MySQL+PHP ...