Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Functional Reactive Programming
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Oscar Swanros
February 18, 2015
Programming
130
1
Share
Functional Reactive Programming
Functional Reactive Programming 101.
Oscar Swanros
February 18, 2015
More Decks by Oscar Swanros
See All by Oscar Swanros
Applied Concurrency: NOT from the ground up
oscarswanros
0
110
Lessons From Becoming an SDK Developer
oscarswanros
0
73
Objective-C & Swift: Interoperability Tips and Tricks
oscarswanros
0
170
What Lies Under The Syntax Sugar
oscarswanros
0
260
Apps Para iOS: De Diseño a Implementación
oscarswanros
0
96
Becoming a Better iOS Developer Through Tooling
oscarswanros
0
2.8k
Mejores Prácitcas Para el Desarrollo de Aplicaciones iOS con Swift
oscarswanros
0
140
Architecting iOS Apps for Fun & Profit
oscarswanros
0
210
Android Elements & Design Patterns
oscarswanros
0
75
Other Decks in Programming
See All in Programming
Offline should be the norm: building local-first apps with CRDTs & Kotlin Multiplatform
renaudmathieu
0
200
Make GenAI Production-Ready with Kubernetes Patterns
bibryam
0
110
ハンズオンで学ぶクラウドネイティブ
tatsukiminami
0
120
ハーネスエンジニアリングにどう向き合うか 〜ルールファイルを超えて開発プロセスを設計する〜 / How to approach harness engineering
rkaga
20
8.5k
Vibe NLP for Applied NLP
inesmontani
PRO
0
390
ネイティブアプリとWebフロントエンドのAPI通信ラッパーにおける共通化の勘所
suguruooki
0
260
Xdebug と IDE による デバッグ実行の仕組みを見る / Exploring-How-Debugging-Works-with-Xdebug-and-an-IDE
shin1x1
0
370
AWS re:Invent 2025の少し振り返り + DevOps AgentとBacklogを連携させてみた
satoshi256kbyte
3
160
RSAが破られる前に知っておきたい 耐量子計算機暗号(PQC)入門 / Intro to PQC: Preparing for the Post-RSA Era
mackey0225
3
130
Going Multiplatform with Your Android App (Android Makers 2026)
zsmb
2
400
Getting more out of Maven
mlvandijk
0
110
今年もTECHSCOREブログを書き続けます!
hiraoku101
0
250
Featured
See All Featured
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
97
What does AI have to do with Human Rights?
axbom
PRO
1
2.1k
The Invisible Side of Design
smashingmag
302
51k
The browser strikes back
jonoalderson
0
960
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
290
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
150
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
770
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
430
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
93
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
250
Paper Plane (Part 1)
katiecoart
PRO
0
6.6k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
320
Transcript
Func%onal)Reac%ve)Programming Oscar&Swanros MobileCoder.mx mobilecoder.mx,-2015 1
@Swanros h"p:/ /swanros.com mobilecoder.mx,-2015 2
I"got"bored. mobilecoder.mx,-2015 3
Un#l... mobilecoder.mx,-2015 4
WWDC$'14 mobilecoder.mx,-2015 5
I'm$running$away$from$OOP$and$the$ MVC$pa9ern. mobilecoder.mx,-2015 6
And$also$a$li*le$bit$ of... mobilecoder.mx,-2015 7
typedef (^myBlock)(BOOL isThisCool) = ^void() { // }; mobilecoder.mx,-2015 8
Callback'hell,'anyone? mobilecoder.mx,-2015 9
Because'it'gets'boring'quickly... ! mobilecoder.mx,-2015 10
Enter&FRP. mobilecoder.mx,-2015 11
Func%onal)Reac%ve)Programming = Func%onal)Programming)+)Reac%ve)Programming mobilecoder.mx,-2015 12
Func%onal)Programming In#a#purely'func+onal#language,#f(x)#will#return#the#same#value#for# the#same#x. Always. mobilecoder.mx,-2015 13
Reac%ve'Programming In#a#reac%ve#language,#y=f(x) y!will!always!stay!up!to!date!when!x! changes. mobilecoder.mx,-2015 14
mobilecoder.mx,-2015 15
FRP!is!about!datatypes!that! represent!a!value!over!&me. mobilecoder.mx,-2015 16
At#the#core#of#FRP#are#Signals. mobilecoder.mx,-2015 17
A"Signal"is"a"value"that"changes"over()me. mobilecoder.mx,-2015 18
done := make(chan bool) watcher := notificator.New() for { select
{ case newText := <-watcher.Next: fmt.Println(newText) case error := <-watcher.Error: log.Fatal(error) } } <-done mobilecoder.mx,-2015 19
[self.emailTextField.rac_textSignal subscribeNext:^(id value) { NSLog(@"%@", value); }]; mobilecoder.mx,-2015 20
mobilecoder.mx,-2015 21
@interface ViewController()<UITextFieldDelegate> // ... self.emailTextField.delegate = self; // ... -(BOOL)textField:(UITextField
*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSLog(@"%@", [textField.text stringByAppendingString:string]); return YES; } mobilecoder.mx,-2015 22
[self.emailTextField.rac_textSignal subscribeNext:^(id value) { NSLog(@"%@", value); }]; mobilecoder.mx,-2015 23
// 1 RACSignal *usernameTextSignal = self.usernameTextField.rac_textSignal; RACSignal *passwordTextSignal = self.passwordTextField.rac_textSignal;
// 2 RACSignal *validUsernameSignal = [[usernameTextSignal map:^id(NSString *username) { return @([self isValidUsername:username]); }] distinctUntilChanged]; RACSignal *validPasswordSignal = [[passwordTextSignal map:^id(NSString *password) { return @([self isValidPassword:password]); }] distinctUntilChanged]; // 3 RAC(self.usernameTextField, backgroundColor) = [validUsernameSignal map:^id(NSNumber *usernameValid) { return [usernameValid boolValue] ? [UIColor greenColor] : [UIColor redColor]; }]; RAC(self.passwordTextField, backgroundColor) = [validPasswordSignal map:^id(NSNumber *passwordValid) { return [passwordValid boolValue] ? [UIColor greenColor] : [UIColor redColor]; }]; // 4 [[RACSignal combineLatest:@[validUsernameSignal, validPasswordSignal] reduce:^id(NSNumber *usernameValid, NSNumber *passwordValid){ return @([usernameValid boolValue] == YES && [passwordValid boolValue] == YES); }] subscribeNext:^(NSNumber *loginButtonActive) { self.loginButton.enabled = [loginButtonActive boolValue]; }]; mobilecoder.mx,-2015 24
mobilecoder.mx,-2015 25
Func%onal)Reac%ve)Programming)lets)you)be)more)concise)with)your)code. mobilecoder.mx,-2015 26
Focus&on&what&you&want&to&do, and$not$on$how$to$do$it. mobilecoder.mx,-2015 27
(That's(the(Func.onal(mo#o.) mobilecoder.mx,-2015 28
Resources? mobilecoder.mx,-2015 29
Ruby:&frapuccino class Button def push emit(:pushed) end end button =
Button.new stream = Frappuccino::Stream.new(button) counter = stream .map {|event| event == :pushed ? 1 : 0 } .inject(0) {|sum, n| sum + n } counter.now # => 0 button.push counter.now # => 1 mobilecoder.mx,-2015 30
JS:$RxJS var source = getStockData(); source .filter(function (quote) { return
quote.price > 30; }) .map(function (quote) { return quote.price; }) .forEach(function (price) { console.log('Prices higher than $30: $' + price); }); mobilecoder.mx,-2015 31
Learning(FRP(is(hard. mobilecoder.mx,-2015 32
But$it's$worth$it. mobilecoder.mx,-2015 33
Ques%ons? mobilecoder.mx,-2015 34