SlideShare a Scribd company logo
Taming Asynchronous
Transforms with
Interstellar
let me = Person(name: "Jens Ravens", company: "nerdgeschoss")
@JensRavens
GitHub: JensRavens
jensravens.com
nerdgeschoss.de
A short introduction to
functional programming, the
universe and everything.
In the beginning McIlroy
created the unix pipe. And he
saw it was good.
ls | grep *.jpg | sort
Optionals
and Results
Optionals are a box containing
something.
struct Cat {
func pet() -> String {
return "purrr"
}
}
let boxContainingCat: Optional<Cat> = Cat()
let sound: String?
if let cat = boxContainingCat {
sound = cat.pet()
} else {
sound = nil
}
struct Cat {
func pet() -> String {
return "purrr"
}
}
let boxContainingCat: Optional<Cat> = Cat()
let sound = boxContainingCat?.pet()
struct Cat {
func pet() -> String {
return "purrr"
}
}
let boxContainingCat: Optional<Cat> = Cat()
let sound = boxContainingCat.map { cat in cat.pet() }
struct Cat {
func pet() -> String? {
return "purrr"
}
}
let boxContainingCat: Optional<Cat> = Cat()
let sound: String?? = boxContainingCat.map {
cat in cat.pet()
}
struct Cat {
func pet() -> String? {
return "purrr"
}
}
let boxContainingCat: Optional<Cat> = Cat()
let sound: String? = boxContainingCat.flatMap {
cat in cat.pet()
}
func double(i: Int) -> [Int] { return [i, 2*i] }
[1, 2, 3].map(double) // [[1,2], [2,4], [3,6]]
[1, 2, 3].flatMap(double) // [[1, 2, 2,4, 3,6]
Error Handling
Buy it, use it,
break it, fix it,
Trash it, change it,
mail - upgrade it.
– Daft Punk, Technologic
Buy it;
if error {
//TODO: Handle me!
} else {
use it;
if error {
//TODO: Handle me!
} else {
break it;
if error {
//TODO: Handle me!
enum Result<T> {
case Success(T)
case Error(ErrorType)
func map<U>(f: T -> U) -> Result<U>
func flatMap<U>(f: T -> Result<U>) -> Result<U>
}
func ls()-> Result<[String]>
func grep(pattern: String)(values: [String]) -> [String]
func sort(values: [String]) -> [String] { return [] }
let sorted = ls().map(grep("*.jpg")).map(sort)
ls | grep *.jpg | sort
Interstellar
ls | grep *.jpg | sort
class Signal<T> {
func subscribe(f: Result<T> -> Void) -> Signal<T>
func next(g: T -> Void) -> Signal<T>
func error(g: ErrorType -> Void) -> Signal<T>
func update(result: Result<T>)
func update(value: T)
func update(error: ErrorType)
}
let signal = Signal<String>()
signal.next { string in print(string) }
signal.update("Hello World")
pushing instead of pulling
But what about
Threads?
let threadSignal = Signal<String>()
func uppercase(string: String) -> String {
return string.uppercaseString
}
threadSignal
.ensure(Thread.background)
.map(uppercase)
.ensure(Thread.main)
.next { print($0) }
Extending UIKit to
support Signals.
extension UITextField {
public var textSignal: Signal<String>
}
let textField = UITextField()
textField.textSignal.next { string in print(string) }
If it’s variable, it qualifies
as a Signal.
real world code examples
func executeRequest(request: Request) -> Signal<HTTPResponse>
func getURL(response: HTTPResponse) throws -> NSURL
func upload(data: NSData)(url: NSURL, completion:
Result<String>->Void)
func createEntity(path: String, completion:
Result<Conversation>->Void)
func createConversation(avatar: UIImage) ->
Signal<Conversation> {
let signal = Signal<Conversation>()
let data = UIImageJPEGRepresentation(avatar, 0.8)!
api
.executeRequest(.GetUploadURL)
.flatMap(getURL)
.flatMap(api.upload(data))
.flatMap(createEntity)
.subscribe(signal.update)
return signal
}
func poll() -> Signal<[Conversation]> {
let signal = Signal<[Conversation]>()
let json = api
.executeRequest(.GetConversations)
.map { $0.json }
let conversations = json
.flatMap(Sync<Conversation>(context: context).updateObjects)
let messages = json
.flatMap(getMessages)
.flatMap(Sync<Message>(context: context).updateObjects)
conversations.merge(messages)
.flatMap(context.saveAndPipe)
.next { signal.update($0.0) }
.error { signal.update($0) }
signal.map(countUnread).next(setUnreadCount)
return signal
}
func poll() -> Signal<[Conversation]> {
let signal = Signal<[Conversation]>()
let json = api
.executeRequest(.GetConversations)
.map { $0.json }
let conversations = json
.flatMap(Sync<Conversation>(context: context).updateObjects)
let messages = json
.flatMap(getMessages)
.flatMap(Sync<Message>(context: context).updateObjects)
conversations.merge(messages)
.flatMap(context.saveAndPipe)
.next { signal.update($0.0) }
.error { signal.update($0) }
signal.map(countUnread).next(setUnreadCount)
return signal
}
API Request
sync conversations
sync messages
wait for both
then save
update unread
count
notify listeners
Warpdrive
• Thread.main / Thread.background
• Signal.delay(seconds: NSTimeInterval)
• Signal.wait throws
• Signal.debounce(seconds: NSTimeInterval)
Coming soon:
Holodeck UIKit Bindings
Thank you.
@JensRavens
github.com/jensravens/interstellar

More Related Content

PDF
The Ring programming language version 1.10 book - Part 45 of 212
PPTX
Kotlin standard
PPTX
Kotlin class
PPTX
Kotlin collections
PPSX
Scala @ TomTom
PPTX
Столпы функционального программирования для адептов ООП, Николай Мозговой
DOCX
CLUSTERGRAM
PDF
Music as data
The Ring programming language version 1.10 book - Part 45 of 212
Kotlin standard
Kotlin class
Kotlin collections
Scala @ TomTom
Столпы функционального программирования для адептов ООП, Николай Мозговой
CLUSTERGRAM
Music as data

What's hot (20)

PDF
Csharp_Chap13
PDF
The Ring programming language version 1.3 book - Part 25 of 88
PDF
The Ring programming language version 1.5.2 book - Part 34 of 181
PPTX
Cassandra Summit - What's New In Apache TinkerPop?
PDF
The Ring programming language version 1.5.4 book - Part 23 of 185
PDF
Hw09 Hadoop + Clojure
PDF
The Ring programming language version 1.5.4 book - Part 35 of 185
PDF
Functional Programming inside OOP? It’s possible with Python
PDF
The Ring programming language version 1.10 book - Part 43 of 212
PDF
Phil Bartie QGIS PLPython
PDF
Go ahead, make my day
PDF
The Ring programming language version 1.10 book - Part 31 of 212
PDF
Beyond tf idf why, what & how
PDF
The Ring programming language version 1.5.1 book - Part 33 of 180
PDF
OCamlOScope: a New OCaml API Search
PPTX
F# Presentation for SmartDevs, Hereford
PPTX
Data made out of functions
PDF
The Ring programming language version 1.6 book - Part 37 of 189
PDF
ScalaMeter 2014
PPTX
Curry functions in Javascript
Csharp_Chap13
The Ring programming language version 1.3 book - Part 25 of 88
The Ring programming language version 1.5.2 book - Part 34 of 181
Cassandra Summit - What's New In Apache TinkerPop?
The Ring programming language version 1.5.4 book - Part 23 of 185
Hw09 Hadoop + Clojure
The Ring programming language version 1.5.4 book - Part 35 of 185
Functional Programming inside OOP? It’s possible with Python
The Ring programming language version 1.10 book - Part 43 of 212
Phil Bartie QGIS PLPython
Go ahead, make my day
The Ring programming language version 1.10 book - Part 31 of 212
Beyond tf idf why, what & how
The Ring programming language version 1.5.1 book - Part 33 of 180
OCamlOScope: a New OCaml API Search
F# Presentation for SmartDevs, Hereford
Data made out of functions
The Ring programming language version 1.6 book - Part 37 of 189
ScalaMeter 2014
Curry functions in Javascript
Ad

Viewers also liked (11)

PPTX
Presentazione Tambeach
PPTX
Business finance
PDF
Productive Android developers (Meetup slides)
PPT
през цапукда ярославль тур 271216_резюме
PPT
Thriller development paul
PDF
FPBP Brochure - Get Care Get Covered
PDF
Building Business – Marketing Candidates
DOCX
Ben
PPTX
Přednáška V3C: Vyhodnocení dotazníků
PDF
Nikhil Bagde Software Engineer
PDF
Kerääjäkasveilla ravinteet talteen, Sari Iivonen, Helsingin yliopisto
Presentazione Tambeach
Business finance
Productive Android developers (Meetup slides)
през цапукда ярославль тур 271216_резюме
Thriller development paul
FPBP Brochure - Get Care Get Covered
Building Business – Marketing Candidates
Ben
Přednáška V3C: Vyhodnocení dotazníků
Nikhil Bagde Software Engineer
Kerääjäkasveilla ravinteet talteen, Sari Iivonen, Helsingin yliopisto
Ad

Similar to Taming Asynchronous Transforms with Interstellar (20)

PDF
Functional Reactive Programming without Black Magic (UIKonf 2015)
PDF
InterConnect: Server Side Swift for Java Developers
PDF
ReactiveCocoa workshop
PDF
From android/java to swift (3)
PDF
Asynchronous swift
PDF
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
PDF
Let'swift "Concurrency in swift"
PDF
Quick swift tour
PDF
Mobile Fest 2018. Александр Корин. Болеутоляющее
PDF
Swift rocks! #1
PDF
Fun with functions
PDF
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
PDF
Introduction to Swift
PDF
ReactiveCocoa and Swift, Better Together
PDF
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
PDF
The Swift Compiler and Standard Library
PDF
Developing Swift - Moving towards the future
PDF
Swift Programming Language
PDF
Intro toswift1
KEY
Beauty and Power of Go
Functional Reactive Programming without Black Magic (UIKonf 2015)
InterConnect: Server Side Swift for Java Developers
ReactiveCocoa workshop
From android/java to swift (3)
Asynchronous swift
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
Let'swift "Concurrency in swift"
Quick swift tour
Mobile Fest 2018. Александр Корин. Болеутоляющее
Swift rocks! #1
Fun with functions
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Introduction to Swift
ReactiveCocoa and Swift, Better Together
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
The Swift Compiler and Standard Library
Developing Swift - Moving towards the future
Swift Programming Language
Intro toswift1
Beauty and Power of Go

More from Jens Ravens (9)

PDF
Turning it up to 11 - Scaling Ruby on Rails to 100k rps
PDF
Server Side Swift - AppBuilders 2017
PDF
Server Side Swift
PDF
Working with Xcode and Swift Package Manager
PDF
Server Side Swift with Swag
PDF
Hipster oriented programming (Mobilization Lodz 2015)
PDF
Hipster Oriented Programming
PDF
Swift 2
PDF
Swift: Immutability and You
Turning it up to 11 - Scaling Ruby on Rails to 100k rps
Server Side Swift - AppBuilders 2017
Server Side Swift
Working with Xcode and Swift Package Manager
Server Side Swift with Swag
Hipster oriented programming (Mobilization Lodz 2015)
Hipster Oriented Programming
Swift 2
Swift: Immutability and You

Recently uploaded (20)

PPTX
Essential Infomation Tech presentation.pptx
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
Transform Your Business with a Software ERP System
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
Introduction to Artificial Intelligence
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
top salesforce developer skills in 2025.pdf
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
System and Network Administraation Chapter 3
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Nekopoi APK 2025 free lastest update
PDF
Understanding Forklifts - TECH EHS Solution
Essential Infomation Tech presentation.pptx
Softaken Excel to vCard Converter Software.pdf
CHAPTER 2 - PM Management and IT Context
Transform Your Business with a Software ERP System
How Creative Agencies Leverage Project Management Software.pdf
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Odoo POS Development Services by CandidRoot Solutions
Introduction to Artificial Intelligence
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Odoo Companies in India – Driving Business Transformation.pdf
top salesforce developer skills in 2025.pdf
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Which alternative to Crystal Reports is best for small or large businesses.pdf
System and Network Administraation Chapter 3
Design an Analysis of Algorithms I-SECS-1021-03
How to Migrate SBCGlobal Email to Yahoo Easily
Nekopoi APK 2025 free lastest update
Understanding Forklifts - TECH EHS Solution

Taming Asynchronous Transforms with Interstellar

  • 2. let me = Person(name: "Jens Ravens", company: "nerdgeschoss") @JensRavens GitHub: JensRavens jensravens.com nerdgeschoss.de
  • 3. A short introduction to functional programming, the universe and everything.
  • 4. In the beginning McIlroy created the unix pipe. And he saw it was good. ls | grep *.jpg | sort
  • 6. Optionals are a box containing something.
  • 7. struct Cat { func pet() -> String { return "purrr" } } let boxContainingCat: Optional<Cat> = Cat() let sound: String? if let cat = boxContainingCat { sound = cat.pet() } else { sound = nil }
  • 8. struct Cat { func pet() -> String { return "purrr" } } let boxContainingCat: Optional<Cat> = Cat() let sound = boxContainingCat?.pet()
  • 9. struct Cat { func pet() -> String { return "purrr" } } let boxContainingCat: Optional<Cat> = Cat() let sound = boxContainingCat.map { cat in cat.pet() }
  • 10. struct Cat { func pet() -> String? { return "purrr" } } let boxContainingCat: Optional<Cat> = Cat() let sound: String?? = boxContainingCat.map { cat in cat.pet() }
  • 11. struct Cat { func pet() -> String? { return "purrr" } } let boxContainingCat: Optional<Cat> = Cat() let sound: String? = boxContainingCat.flatMap { cat in cat.pet() }
  • 12. func double(i: Int) -> [Int] { return [i, 2*i] } [1, 2, 3].map(double) // [[1,2], [2,4], [3,6]] [1, 2, 3].flatMap(double) // [[1, 2, 2,4, 3,6]
  • 14. Buy it, use it, break it, fix it, Trash it, change it, mail - upgrade it. – Daft Punk, Technologic
  • 15. Buy it; if error { //TODO: Handle me! } else { use it; if error { //TODO: Handle me! } else { break it; if error { //TODO: Handle me!
  • 16. enum Result<T> { case Success(T) case Error(ErrorType) func map<U>(f: T -> U) -> Result<U> func flatMap<U>(f: T -> Result<U>) -> Result<U> }
  • 17. func ls()-> Result<[String]> func grep(pattern: String)(values: [String]) -> [String] func sort(values: [String]) -> [String] { return [] } let sorted = ls().map(grep("*.jpg")).map(sort) ls | grep *.jpg | sort
  • 19. ls | grep *.jpg | sort
  • 20. class Signal<T> { func subscribe(f: Result<T> -> Void) -> Signal<T> func next(g: T -> Void) -> Signal<T> func error(g: ErrorType -> Void) -> Signal<T> func update(result: Result<T>) func update(value: T) func update(error: ErrorType) } let signal = Signal<String>() signal.next { string in print(string) } signal.update("Hello World")
  • 23. let threadSignal = Signal<String>() func uppercase(string: String) -> String { return string.uppercaseString } threadSignal .ensure(Thread.background) .map(uppercase) .ensure(Thread.main) .next { print($0) }
  • 25. extension UITextField { public var textSignal: Signal<String> } let textField = UITextField() textField.textSignal.next { string in print(string) }
  • 26. If it’s variable, it qualifies as a Signal.
  • 27. real world code examples
  • 28. func executeRequest(request: Request) -> Signal<HTTPResponse> func getURL(response: HTTPResponse) throws -> NSURL func upload(data: NSData)(url: NSURL, completion: Result<String>->Void) func createEntity(path: String, completion: Result<Conversation>->Void) func createConversation(avatar: UIImage) -> Signal<Conversation> { let signal = Signal<Conversation>() let data = UIImageJPEGRepresentation(avatar, 0.8)! api .executeRequest(.GetUploadURL) .flatMap(getURL) .flatMap(api.upload(data)) .flatMap(createEntity) .subscribe(signal.update) return signal }
  • 29. func poll() -> Signal<[Conversation]> { let signal = Signal<[Conversation]>() let json = api .executeRequest(.GetConversations) .map { $0.json } let conversations = json .flatMap(Sync<Conversation>(context: context).updateObjects) let messages = json .flatMap(getMessages) .flatMap(Sync<Message>(context: context).updateObjects) conversations.merge(messages) .flatMap(context.saveAndPipe) .next { signal.update($0.0) } .error { signal.update($0) } signal.map(countUnread).next(setUnreadCount) return signal }
  • 30. func poll() -> Signal<[Conversation]> { let signal = Signal<[Conversation]>() let json = api .executeRequest(.GetConversations) .map { $0.json } let conversations = json .flatMap(Sync<Conversation>(context: context).updateObjects) let messages = json .flatMap(getMessages) .flatMap(Sync<Message>(context: context).updateObjects) conversations.merge(messages) .flatMap(context.saveAndPipe) .next { signal.update($0.0) } .error { signal.update($0) } signal.map(countUnread).next(setUnreadCount) return signal } API Request sync conversations sync messages wait for both then save update unread count notify listeners
  • 32. • Thread.main / Thread.background • Signal.delay(seconds: NSTimeInterval) • Signal.wait throws • Signal.debounce(seconds: NSTimeInterval) Coming soon: Holodeck UIKit Bindings