Laziness in Swift
by Joachim Kurz (@cocoafrog)
Mobile2b GmbH
iOSDevUK 2014
Lazy Evaluation
•
Delay computation of a value until it is
actually needed
•
•
Increases expressiveness
•
iOSDevUK 2014
Avoid unnecessary computations
E.g. handle infinite lists
Joachim Kurz, Mobile2b GmbH
Lazy Sequences
in Swift
by Joachim Kurz (@cocoafrog)
Mobile2b GmbH
iOSDevUK 2014
Lazy Infinite Sequences
in Swift
by Joachim Kurz (@cocoafrog)
Mobile2b GmbH
iOSDevUK 2014
Build an Infinite Sequences
protocol SequenceType : _Sequence_Type {
typealias Generator : GeneratorType
func generate() -> Generator
}
protocol GeneratorType {
typealias Element
!
/// If all elements are exhausted, return `nil`.
Otherwise, advance
/// to the next element and return it.
mutating func next() -> Element?
}
iOSDevUK 2014
Joachim Kurz, Mobile2b GmbH
Sequence of Natural Numbers
!
!
var current = 0
!
func next() {
current++
return current
}
!
iOSDevUK 2014
Joachim Kurz, Mobile2b GmbH
Sequence of Natural Numbers
!
!
var current = 0
!
return GeneratorOf<Int>({
current++
return current
})
!
iOSDevUK 2014
Joachim Kurz, Mobile2b GmbH
Sequence of Natural Numbers
!
func generate() -> GeneratorOf<Int> {
var current = 0
!
}
iOSDevUK 2014
return GeneratorOf<Int>({
current++
return current
})
Joachim Kurz, Mobile2b GmbH
Sequence of Natural Numbers
struct NaturalNumbers : SequenceType {
func generate() -> GeneratorOf<Int> {
var current = 0
!
}
iOSDevUK 2014
}
return GeneratorOf<Int>({
current++
return current
})
Joachim Kurz, Mobile2b GmbH
Sequence of Natural Numbers
let naturalNumbers = NaturalNumbers()
!
for i in naturalNumbers {
if (i > 9) {
break;
}
println(i)
}
iOSDevUK 2014
Joachim Kurz, Mobile2b GmbH
Prints
1
2
3
4
5
6
7
8
9
Create lazy collections using
lazy()
iOSDevUK 2014
•
lazy() creates a lazy collection/sequence
out of an existing collection/sequence
•
Implementations of .filter() and .map()
but they will only be evaluated for an element
when that element is accessed
•
But: evaluated on each access
Joachim Kurz, Mobile2b GmbH
Fun with lazy() natural numbers
let lazyNats = lazy(NaturalNumbers())
let natural3s = lazyNats.filter({ $0 % 3
!
for i in natural3s {
if (i > 38) { break; }
print("\(i),")
}
3,6,9,12,15,18,21,24,27,30,33,36,
iOSDevUK 2014
Joachim Kurz, Mobile2b GmbH
== 0})
Fun with lazy() natural numbers
let lazyNats = lazy(NaturalNumbers())
let natural3s = lazyNats.filter {
println("check \($0)")
return $0 % 3 == 0
}
!
for i in natural3s {
if (i > 9) { break; }
println(i)
}
iOSDevUK 2014
Joachim Kurz, Mobile2b GmbH
check
check
check
3
check
check
check
6
check
check
check
9
check
check
check
1
2
3
4
5
6
7
8
9
10
11
12
Fun with lazy() natural numbers
let logsOfNaturalNumbers = lazyNats.map{
log(Double($0))
}
println(logsOfNaturalNumbers.first_n¹(10).array)
[0.0, 0.693147180559945,
1.09861228866811, 1.38629436111989,
1.6094379124341, 1.79175946922805,
1.94591014905531, 2.07944154167984,
2.19722457733622, 2.30258509299405]
¹ not part of the standard library, but should be
iOSDevUK 2014
Joachim Kurz, Mobile2b GmbH
filter
infinite Fibonacci Sequence
let lazyFibs = lazy(FibonacciSequence())
!
!
let firstFewFibs = lazyFibs.first_n(17).array
!
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1,597]
!
!
let primeFibonacciNumbers = lazyFibs.filter(isPrime)
let firstFewPrimeFibs = primeFibonacciNumbers.first_n(8).array
!
[2, 3, 5, 13, 89, 233, 1,597, 28,657]
iOSDevUK 2014
Joachim Kurz, Mobile2b GmbH
Laziness in Swift
•
lazy()
•
•
@autoclosure
•
•
lazy(FibonacciSequence())
func value(value: @autoclosure () -> Int)
lazy properties
•
iOSDevUK 2014
lazy var y:Int = expensiveCalculation()
Joachim Kurz, Mobile2b GmbH (@cocoafrog)
© Copyright 2026 Paperzz