Functional Reactive Programming

Functional Reactive Programming

B433b981e15d8f2373df4363352434f9?s=128

halfrost

June 15, 2017
Tweet

Transcript

  1. FRP & RAC 冰霜

  2. 什么是函数响应式?

  3. 命令式 VS 函数式 int factorial(int x){ if (x < 0)

    return INT_MIN; int result = 1; for (int i = 1; i <= x ; ++i) { result *= i; } return result; } 1. 如何计算 2. 表达式和语句 3. 状态量 函数式编程⾥⾯是基本上没有状态量,只有表达式,也没有赋值语句。利⽤了递归解决了问题。 int factorial(int x){ if (x < 0) return INT_MIN; if (x==1) return 1; return x * factorial(x-1); }
  4. 命令式 VS 响应式 09:30 Magna Amet 05:20 AM 09:45 PM

    Euismod, Ipsum void react() { int a = 8; int b = 9; int c = a + b; a = 10; NSLog(@"%d", c); } 在⾯向对象语⾔中也是可以实现响应式编程的,具体做法应该是,把关系抽象出来,然后把 变化抽象出来,⽤关系把变化事件传递下去。Cocoa框架下RAC的实现就是如此。
  5. Cum sociis natoque penatibus et magnis parturient montes. 在计算机编程中,假如满⾜下⾯这两 个句⼦的约束,⼀个函数可能被描述

    为⼀个纯函数: 1. 给出同样的参数值,该函数总是 求出同样的结果。该函数结果值不 依赖任何隐藏信息或程序执⾏处理 可能改变的状态或在程序的两个不 同的执⾏,也不能依赖来⾃I/O装置 的任何外部的输⼊(通常是这样的 --看下⾯的描述)。 2. 结果的求值不会促使任何可语义 上可观察的副作⽤或输出,例如易 变对象的变化或输出到I/O装置。 纯函数 函数的返回值是不需要依赖所有(或任 何)参数值,必须不依赖参数值以外的 东⻄。函数可能返回多重结果值,并且 对于被认为是纯函数的函数,这些条件 必须应⽤到所有返回值。假如⼀个参数通 过引⽤调⽤,任何内部参数变化将改变函 数外部的输⼊参数值,它将使函数变为⾮ 纯函数。 ⼀个纯函数在执⾏的过程中,只跟 ⼊参有关,在函数体中并不会引⽤ 外部全局变量,或者说是⼀个类⽅ 法⾥⾯的其他成员变量。另外,纯 函数除了返回值之外,也不会去改 变外部的变量值。满⾜上⾯这两点 的纯函数,就可以说它是引⽤透明 的。也有说法叫这种特性为幂等性
  6. 副作⽤ ⼀等函数的理念可以追溯到 Church 的 lambda 演算 (Church 1941; Barendregt 1984)。此后,包括

    Haskell,OCaml,Standard ML,Scala 和 F# 在内的⼤量 (函数式) 编程语⾔都不同程度地借鉴了这个概念。 PS:世界上最纯粹的函数式编程语⾔⾮Haskell莫属。 函数式编程强调没有"副作⽤",意味着函数要保持 独⽴,所有功能就是返回⼀个新的值,没有其他⾏ 为,尤其是不得修改外部变量的值。
  7. 函数式编程Functional Programming 1. 函数是"第⼀等公⺠" 2. 闭包和⾼阶函数 3. 不改变状态 4. 递归

    5. 只⽤"表达式",不⽤"语句",没有副作⽤ 85% 50% 76% 95% Functional Programming is a programming paradigm 1. treats computation as the evaluation of mathematical functions. 2. avoids changing-state and mutable data 所谓"第⼀等公⺠"(first class),指的是函数与其他数据类型⼀样,处于平等地位,可以赋值给其他变量,也可 以作为参数,传⼊另⼀个函数,或者作为别的函数的返回值。
  8. 函数响应式编程FUNCTIONAL REACTIVE PROGRAMMING 函数响应式编程是⾯向离散事件流的,在⼀个时间轴上会产⽣ ⼀些离散事件,这些事件会依次向下传递。 RAC就是Cocoa框架下的函数响应式编程的实现。它提供了基 于时间变化的数据流的组合和变化。 明⽩了!

  9. ⾯向对象编程 Object Oriented Programming 响应式编程 Reactive Programming 函数式编程 Functional Programming

    函数响应式编程 Functional Reactive Programming
  10. Tortor Sem Dapibus

  11. Tortor Sem Dapibus

  12. Github Mac 客户端附产物 01 FRP在Cocoa框架下的实现 02 富含了Cocoa框架下的多种组 件 03 提供了基于时间变化的数据流

    的组合和变换的操作 04 简称 RAC 05 什么是 ReactiveCoCoa ?
  13. Reactive Objc

  14. RACSequence VS RACSignal Pull-Driver Data Push-Driver Event

  15. RACDisposable RACScheduler RACCommand RACSubscriber

  16. RAC 基础 RACSignal *signal = [RACSignal createSignal: ^RACDisposable *(id<RACSubscriber> subscriber)

    { [subscriber sendNext:@1]; [subscriber sendNext:@2]; [subscriber sendNext:@3]; [subscriber sendCompleted]; return [RACDisposable disposableWithBlock:^{ NSLog(@"signal dispose"); }]; }]; RACDisposable *disposable = [signal subscribeNext:^(id x) { NSLog(@"subscribe value = %@", x); } error:^(NSError *error) { NSLog(@"error: %@", error); } completed:^{ NSLog(@"completed"); }]; [disposable dispose];
  17. 单个信号的变换 RACSignal 的各类操作

  18. RACSignal

  19. RACSignal

  20. RACSignal

  21. RACSignal

  22. RACSignal

  23. RACSignal

  24. RACSignal

  25. RACSignal

  26. RACSignal

  27. 85% 50% 76% 95% 数量操作 RACSignal 的各类操作

  28. RACSignal

  29. RACSignal

  30. RACSignal

  31. RACSignal

  32. RACSignal

  33. RACSignal

  34. RACSignal

  35. RACSignal

  36. RACSignal

  37. RACSignal

  38. RACSignal

  39. RACSignal

  40. RACSignal

  41. RACSignal Repeat 操作 Signal A ——‘AA’——‘BB’—|————————— Signal B ——‘AA’——‘BB’———‘AA’——‘BB’———‘AA’——‘BB’—

  42. 时间操作 RACSignal 的各类操作

  43. RACSignal + (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;

  44. RACSignal 如何得到⼀个每隔⼀秒延迟发送⼀个值的⽆限信号? (假设每个值都是1,即[RACSignal return:@1]) RACSignal *interval = [[[RACSignal return:@1] delay:1]

    repeat]; 如何把下⾯这个信号每个值中间都插⼊1秒的时间间隔? RACSignal *signal = @[@1, @3, @7, @9, @8].rac_sequence.signal; RACSignal *timerSignal = [[signal map:^id(id value) { return [[RACSignal return:value] delay:1]; }] concat];
  45. RACSignal

  46. 多个信号的组合 RACSignal 的各类操作

  47. RACSignal

  48. RACSignal

  49. RACSignal

  50. RACSignal

  51. RACSignal

  52. RACSignal

  53. Q & A

  54. ANSWER 1. RAC 在哪些场景下可以提⾼开发效率? 可否举个最明显的例⼦。 2. RAC 有哪些缺陷?⽐如RAC的哪些操作 执⾏效率⽐较低? 3.

    如何降低新同事的学习成本?即有⽊有 快速⼊⻔的系列教程可以推荐,适合⼊ ⻔的,中级的,深⼊的。 4. ReactiveCocoa 和 ReactiveSwift 啥关 系? ⼊⻔资料官⽅⽂档 基础⽤法都要熟悉 先回答第三题 中级 多实践,思维的转变,⽤函数式 去思考问题 深⼊ 看源码,了解底层实现,领悟 RAC的精髓。如何不⽤RAC实现 MVVM中的绑定操作?bind 和 Monad 范畴论
  55. 2 3 1 RAC适合的场景 事件处理 切⾯处理 异步场景

  56. 处理成功的回调 01 处理异常和错误 02 ⽀持取消操作 03 subscribenext 01 subscribeError 02

    disposable 03 异步处理 还能有效解决回调地狱的问题 PromiseKit (PromiseKit 是 RAC的 Continuation-Passing Style)
  57. 异步处理 信号的降阶 和升阶 错误传递和 捕获的统⼀ 信号的组合 与变换 线程操作RACScheduler⽅便 01 02

    03
  58. UI事件 事件处理 Delegate RAC对整个UIKit库都有对应的 Category

  59. 切⾯处理 KVO ⽅法调⽤与监听

  60. 同步场景 14% 68% 47% RAC不适合的场景 纯OOP场景 缺陷 调试困难 对新⼿不友好 学习曲线陡峭

  61. 09:30 Magna Amet 05:20 AM 09:45 PM Euismod, Ipsum ReactiveSwift

    是 RAC 在 Swift 语⾔出来以后针对 Swift 的实现。 ReactiveSwift ⾥⾯没有冷信号。全是热信号。 ReactiveSwif 在ReactiveCocoa v2.5中,flatten默认就是flattenMap:这 ⼀种操作。 ReactiveCocoa v3.x,v4.x,v5.x中,flatten的操作是可以 选择3种操作选择的。merge,concat,switchToLatest。 ReactiveCocoa 和 ReactiveSwift
  62. ANSWER 1. RAC 和 Rx 对⽐ 2. MVVM 实践探讨,哪⾥该⽤哪⾥不该⽤ 3.

    双向绑定 vs 单向绑定 4. 如何将事件传递流暴露的更明显,⽽不是 像 notify ⼀样分散 1.RAC 和 Rx 都是采⽤ FRP 思想 实现的⼀个库。RAC有OC版 本,Rx只有Swift版本。Rx家族 API特别⼀致。 第⼆题请⽼⼤回答 3.双向绑定: 当⼀个⼦组件改变了⼀个prop的值 时,这个变化也会同步到⽗组件中所 绑定的值。但也会导致问题。由于⼦ 组件改变prop的代码和普通的状态改 变代码毫⽆差别,当光看⼦组件的代 码时,你完全不知道它何时悄悄地改 变了⽗组件的状态。这在debug复杂 结构的应⽤时会带来很⾼的维护成 本。 4.⽤⼀个消息中⼼或者消息总线来处理
  63. THANK YOU.