Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Introduction to
Functional Reactive
Programming
@EliSawic
About me
Eliasz Sawicki
Blog: www.eliaszsawicki.com
Twitter: @EliSawic
@EliSawic
Agenda
• What is functional reactive programming?
• Working with streams
• ReactiveSwift - Thinking in signals
• Example
@...
Functional Reactive Programming
@EliSawic
Wikipedia
Functional reactive programming (FRP) is a programming
paradigm for reactive programming (asynchronous dataflow
p...
Reactive
Programming
@EliSawic
Functional
Programming
@EliSawic
Blocks
@EliSawic
Imperative
vs
Declarative
@EliSawic
Imperative
@EliSawic
Imperative
let array = [0, 1, 2, 3, 4, 5]
var evenNumbers = [Int]()
for element in array {
if element % 2 == 0 {
evenNumbe...
Declarative
@EliSawic
Declarative
let array = [0, 1, 2, 3, 4, 5]
let evenNumbers = array.filter { $0 % 2 == 0 }
@EliSawic
Working with streams
@EliSawic
Stream
@EliSawic
Manipulating streams
@EliSawic
Map
@EliSawic
Filter
@EliSawic
Aggregating
@EliSawic
Manipulating
multiple streams
@EliSawic
Combine latest
@EliSawic
Merge
@EliSawic
Chaining streams
@EliSawic
www.rxmarbles.com
@EliSawic
ReactiveSwift
@EliSawic
Thinking in Signals
@EliSawic
What is a signal?
@EliSawic
This screen is a signal
@EliSawic
Represents events
over time
@EliSawic
Observing does not
trigger side effects
@EliSawic
No random access to
events
@EliSawic
Observe
@EliSawic
If you don't listen, it's
gone
@EliSawic
What is event?
@EliSawic
Event
struct Idea {
var content: String
var quality: Quality
}
enum Quality {
case Great
case Average
case Worst
}
@EliSaw...
Non-Terminating
• Next
@EliSawic
Terminating
• Completed
• Failed
• Interrupted (Reactive Cocoa)
@EliSawic
Presentation
let (presentation, presentationObserver) = Signal<Idea, NoError>.pipe()
let content = "This presentation is a...
Observing
presentation.observeValues { idea in
remember(idea: idea)
}
presentation.observeCompleted {
print("Time for a br...
Only great ideas
let greatIdeas = presentation.filter { idea in
idea.quality == .Great
}
greatIdeas.observeValues { greatI...
Positive listener
let greatPresentation = presentation.map { idea -> Idea in
var greatIdea = idea
greatIdea.quality = .Gre...
Signal producer
@EliSawic
Represents a tasks
@EliSawic
Possible side effects
@EliSawic
Does not start it's
work if not asked
@EliSawic
Run presentation
func runPresentation() -> SignalProducer<Idea, NoError> {
return SignalProducer { observer, _ in
observer...
Work with presentation
runPresentation().startWithValues { idea in
print(idea)
}
runPresentation().startWithSignal { (sign...
Cold vs Hot
@EliSawic
Properties
@EliSawic
Mutable Property
let firstSlide = Slide(number: 1)
let slide = MutableProperty<Slide>(firstSlide)
slide.producer.startWith...
Bindings
@EliSawic
Binding example
let slideNumber = MutableProperty<Int>(0)
let (signal, _) = Signal<Slide, NoError>.pipe()
slideNumber <~ s...
Binding example
let (signal, _) = Signal<Slide, NoError>.pipe()
label.reactive.text <~ signal.map { return "Slide: ($0.num...
Schedulers
@EliSawic
Know where you are
signal.observe(on: QueueScheduler.main).observeValues { idea in
print("Performing UI updates")
}
@EliSa...
Memory Management
@EliSawic
Disposables
@EliSawic
Free your memory
let disposable = signal.observeValues { value in
...
}
disposable.dispose()
@EliSawic
Release your producers
let disposable = producer.startWithValues { value in
...
}
disposable.dispose()
@EliSawic
Example
@EliSawic
@EliSawic
How does it work?
@EliSawic
Is name valid?
let isValidNameSignal = nameSignal.map { (name) -> Bool in
return name.characters.count > 2
}
@EliSawic
Is surname valid?
let isValidSurnameSignal = surnameSignal.map { (surname) -> Bool in
return surname.characters.count > 2
...
Is mail valid?
let isValidMailSignal = mailSignal.map { (mail) -> Bool in
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-...
Combine Latest
let formDataSignal = combineLatest(
isValidNameSignal,
isValidSurnameSignal,
isValidMailSignal)
@EliSawic
Is form valid?
let isValidFormSignal = formDataSignal.map {
(isValidName, isValidSurname, isValidMail) -> Bool in
return i...
Update the state
isValidFormSignal.observeValues { isValid in
updateButtonWith(state: isValid)
}
@EliSawic
Binding
let isValidForm = MutableProperty<Bool>(false)
isValidForm <~ isFormValidSignal
@EliSawic
Conclusion
@EliSawic
Thank you for your
attention!
sendCompleted()
@EliSawic
Upcoming SlideShare
Loading in …5
×

Code europe

321 views

Published on

Introduction to Functional Reactive Programming - CodeEurope

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Code europe

  1. 1. Introduction to Functional Reactive Programming @EliSawic
  2. 2. About me Eliasz Sawicki Blog: www.eliaszsawicki.com Twitter: @EliSawic @EliSawic
  3. 3. Agenda • What is functional reactive programming? • Working with streams • ReactiveSwift - Thinking in signals • Example @EliSawic
  4. 4. Functional Reactive Programming @EliSawic
  5. 5. Wikipedia Functional reactive programming (FRP) is a programming paradigm for reactive programming (asynchronous dataflow programming) using the building blocks of functional programming (e.g. map, reduce, filter). @EliSawic
  6. 6. Reactive Programming @EliSawic
  7. 7. Functional Programming @EliSawic
  8. 8. Blocks @EliSawic
  9. 9. Imperative vs Declarative @EliSawic
  10. 10. Imperative @EliSawic
  11. 11. Imperative let array = [0, 1, 2, 3, 4, 5] var evenNumbers = [Int]() for element in array { if element % 2 == 0 { evenNumbers.append(element) } } @EliSawic
  12. 12. Declarative @EliSawic
  13. 13. Declarative let array = [0, 1, 2, 3, 4, 5] let evenNumbers = array.filter { $0 % 2 == 0 } @EliSawic
  14. 14. Working with streams @EliSawic
  15. 15. Stream @EliSawic
  16. 16. Manipulating streams @EliSawic
  17. 17. Map @EliSawic
  18. 18. Filter @EliSawic
  19. 19. Aggregating @EliSawic
  20. 20. Manipulating multiple streams @EliSawic
  21. 21. Combine latest @EliSawic
  22. 22. Merge @EliSawic
  23. 23. Chaining streams @EliSawic
  24. 24. www.rxmarbles.com @EliSawic
  25. 25. ReactiveSwift @EliSawic
  26. 26. Thinking in Signals @EliSawic
  27. 27. What is a signal? @EliSawic
  28. 28. This screen is a signal @EliSawic
  29. 29. Represents events over time @EliSawic
  30. 30. Observing does not trigger side effects @EliSawic
  31. 31. No random access to events @EliSawic
  32. 32. Observe @EliSawic
  33. 33. If you don't listen, it's gone @EliSawic
  34. 34. What is event? @EliSawic
  35. 35. Event struct Idea { var content: String var quality: Quality } enum Quality { case Great case Average case Worst } @EliSawic
  36. 36. Non-Terminating • Next @EliSawic
  37. 37. Terminating • Completed • Failed • Interrupted (Reactive Cocoa) @EliSawic
  38. 38. Presentation let (presentation, presentationObserver) = Signal<Idea, NoError>.pipe() let content = "This presentation is a signal" let idea = Idea(content: content, quality: .Great) presentationObserver.send(value: idea) presentationObserver.sendCompleted() @EliSawic
  39. 39. Observing presentation.observeValues { idea in remember(idea: idea) } presentation.observeCompleted { print("Time for a break") } @EliSawic
  40. 40. Only great ideas let greatIdeas = presentation.filter { idea in idea.quality == .Great } greatIdeas.observeValues { greatIdea in remember(idea: greatIdea) } @EliSawic
  41. 41. Positive listener let greatPresentation = presentation.map { idea -> Idea in var greatIdea = idea greatIdea.quality = .Great return greatIdea } @EliSawic
  42. 42. Signal producer @EliSawic
  43. 43. Represents a tasks @EliSawic
  44. 44. Possible side effects @EliSawic
  45. 45. Does not start it's work if not asked @EliSawic
  46. 46. Run presentation func runPresentation() -> SignalProducer<Idea, NoError> { return SignalProducer { observer, _ in observer.send(value: idea1) observer.send(value: idea2) ... observer.sendCompleted() } } @EliSawic
  47. 47. Work with presentation runPresentation().startWithValues { idea in print(idea) } runPresentation().startWithSignal { (signal, _) in signal.observeValues({ idea in print(idea) }) signal.observeCompleted { print("Finally...") } } @EliSawic
  48. 48. Cold vs Hot @EliSawic
  49. 49. Properties @EliSawic
  50. 50. Mutable Property let firstSlide = Slide(number: 1) let slide = MutableProperty<Slide>(firstSlide) slide.producer.startWithValues { (text) in print(text) } slide.value = Slide(number: 2) @EliSawic
  51. 51. Bindings @EliSawic
  52. 52. Binding example let slideNumber = MutableProperty<Int>(0) let (signal, _) = Signal<Slide, NoError>.pipe() slideNumber <~ signal.map { return $0.number } @EliSawic
  53. 53. Binding example let (signal, _) = Signal<Slide, NoError>.pipe() label.reactive.text <~ signal.map { return "Slide: ($0.number)" } @EliSawic
  54. 54. Schedulers @EliSawic
  55. 55. Know where you are signal.observe(on: QueueScheduler.main).observeValues { idea in print("Performing UI updates") } @EliSawic
  56. 56. Memory Management @EliSawic
  57. 57. Disposables @EliSawic
  58. 58. Free your memory let disposable = signal.observeValues { value in ... } disposable.dispose() @EliSawic
  59. 59. Release your producers let disposable = producer.startWithValues { value in ... } disposable.dispose() @EliSawic
  60. 60. Example @EliSawic
  61. 61. @EliSawic
  62. 62. How does it work? @EliSawic
  63. 63. Is name valid? let isValidNameSignal = nameSignal.map { (name) -> Bool in return name.characters.count > 2 } @EliSawic
  64. 64. Is surname valid? let isValidSurnameSignal = surnameSignal.map { (surname) -> Bool in return surname.characters.count > 2 } @EliSawic
  65. 65. Is mail valid? let isValidMailSignal = mailSignal.map { (mail) -> Bool in let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}" let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) return emailTest.evaluateWithObject(mail) } @EliSawic
  66. 66. Combine Latest let formDataSignal = combineLatest( isValidNameSignal, isValidSurnameSignal, isValidMailSignal) @EliSawic
  67. 67. Is form valid? let isValidFormSignal = formDataSignal.map { (isValidName, isValidSurname, isValidMail) -> Bool in return isValidMail && isValidSurname && isValidMail } @EliSawic
  68. 68. Update the state isValidFormSignal.observeValues { isValid in updateButtonWith(state: isValid) } @EliSawic
  69. 69. Binding let isValidForm = MutableProperty<Bool>(false) isValidForm <~ isFormValidSignal @EliSawic
  70. 70. Conclusion @EliSawic
  71. 71. Thank you for your attention! sendCompleted() @EliSawic

×