Slide 1

Slide 1 text

λ is coming to Obj-C: ReactiveCocoa Vladimir @chippcheg Burdukov

Slide 2

Slide 2 text

Imperative

Slide 3

Slide 3 text

Declarative

Slide 4

Slide 4 text

Functional programming λ-calculus

Slide 5

Slide 5 text

Functional programming

Slide 6

Slide 6 text

Pure function • result doesn’t depend on any state • function doesn’t change any external state.

Slide 7

Slide 7 text

Pure function def sqr(x: Int): Int = x * x //> sqr: (x: Int)Int sqr(2) /> res4: Int = 4 def add1(x: Int): Int = x + 1 //> add1: (x: Int)Int add1(4) //> res3: Int = 5 add1(add1(4)) //> res4: Int = 6

Slide 8

Slide 8 text

Higher-order functions

Slide 9

Slide 9 text

Higher-order functions def sqr(x: Int): Int = x * x def sumF(x: Int, y: Int, f: Int => Int) = f(x) + f(y) sumF(3, 4, sqr) //> res5: Int = 25

Slide 10

Slide 10 text

Higher-order functions def sqr(x: Int): Int = x * x def sumF(x: Int, y: Int, f: Int => Int) = f(x) + f(y) sumF(3, 4, sqr) //> res5: Int = 25 sumF(-9, 16, abs) //> res6: Int = 25

Slide 11

Slide 11 text

Tail recursion

Slide 12

Slide 12 text

Tail recursion Lists Head Tail

Slide 13

Slide 13 text

Tail recursion Lists val foo: List[Int] = 1 to 5 toList //> foo : List[Int] = List(1, 2, 3, 4, 5) val foohead = foo.head //> foohead : Int = 1 val footail = foo.tail //> footail : List[Int] = List(2, 3, 4, 5)

Slide 14

Slide 14 text

Tail recursion def sumList(xs: List[Int]): Int = if (xs == Nil) return 0 else return xs.head + sumList(xs.tail) // > sumList: (xs: List[Int])Int ! sumList(foo) //> res3: Int = 15

Slide 15

Slide 15 text

Composition

Slide 16

Slide 16 text

Composition def f(a: String): String = "f(" + a + ")" f("5") //> res11: String = f(5) def g(a: String): String = "g(" + a + “)" g("5") //> res12: String = g(5) f(g("5")) //> res13: String = f(g(5)) def fg = f _ compose g _ //> fg: => String => String fg("5") //> res14: String = f(g(5))

Slide 17

Slide 17 text

Functional programming References •https://www.coursera.org/course/progfun

Slide 18

Slide 18 text

Reactive Programming

Slide 19

Slide 19 text

Reactive Programming 5 10 =SUM(A1;B1) A1 B1 C1

Slide 20

Slide 20 text

Functional Reactive Programming

Slide 21

Slide 21 text

ReactiveCocoa Next step of Objective-C evolution https://github.com/ReactiveCocoa/ReactiveCocoa/

Slide 22

Slide 22 text

Introduction https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/Documentation/

Slide 23

Slide 23 text

Introduction https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/Documentation/ pod

Slide 24

Slide 24 text

RACSequense RACSignal

Slide 25

Slide 25 text

RACSignal

Slide 26

Slide 26 text

RACSignal UISwitch *settingSwitch = [[UISwitch alloc] init]; RACSignal *switchSignal = [settingSwitch rac_signalForControlEvents:UIControlEventValueChanged]; [switchSignal subscribeNext:^(UISwitch *x) { NSLog(@"SWITCH %@", x.on); }]; //SWITCH 0 //SWITCH 1 //SWITCH 0

Slide 27

Slide 27 text

RACSignal signal subscribeNext:

Slide 28

Slide 28 text

RACSignal Composition [[[self.field rac_textSignal] filter:^BOOL(NSString *value) { return value.length >= 8; }] subscribeNext:^(id x) { NSLog(@"%@", x); }];

Slide 29

Slide 29 text

RACSignal Combining signal signal combine reduce YES/NO NSString NSString

Slide 30

Slide 30 text

RACSignal Combining RAC(self.createButton, enabled) = [RACSignal combineLatest:@[self.loginField.rac_textSignal, self.passwordField.rac_textSignal] reduce:^id(NSString *username, NSString *password) { return @(username.length > 0 && password.length > 0); }];

Slide 31

Slide 31 text

RACSequence

Slide 32

Slide 32 text

Binding RAC(self.avatarImageView, image) = RACObserve(self.viewModel, userAvatar);

Slide 33

Slide 33 text

ReactiveCocoa UI extensions • UIActionSheet / UIAlertView • UIButton • UITableViewCell • UIControl (rac_signalForControlEvents:) • UIGestureRecognizer • UITextField

Slide 34

Slide 34 text

UIAlertView Signal UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Something goes wrong" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:@"Retry", nil]; ! [[alertView rac_buttonClickedSignal] subscribeNext:^(NSNumber *buttonNumber) { NSLog(@"alert button: %@", [alertView buttonTitleAtIndex:buttonNumber.intValue]); }];

Slide 35

Slide 35 text

UIButton Command RACCommand *loginCommand = [[RACCommand alloc] initWithEnabled:[RACSignal combineLatest:@[loginField.rac_textSignal, passwordField.rac_textSignal] reduce:^id(NSString *username, NSString *password) { return @(username.length > 0 && password.length > 0); }] signalBlock:^RACSignal *(id input) { return [[JMHSync shared] loginUser:self.loginField.text withPassword:self.passwordField.text]; }]; ! self.createButton.rac_command = loginCommand;

Slide 36

Slide 36 text

UITextField Signal [self.loginField.rac_textSignal subscribeNext:^(NSString *x) { NSLog(@"you entered %@", x); }];

Slide 37

Slide 37 text

Conclusion

Slide 38

Slide 38 text

Questions

Slide 39

Slide 39 text

Thank you!