The document discusses functional programming in Swift. It defines functional programming as avoiding mutable data and state. This means that in functional programming, variables are immutable and do not change value once assigned, and functions have no side effects or dependence on external state. The advantages of this approach include cleaner, more modular code with no hidden state, referential transparency allowing parallelization and memoization, and easier debugging. Functional concepts like immutable objects, higher order functions, lazy evaluation, and recursion are demonstrated in Swift examples.
2. Geison Goes
● Senior Consultant na Thoughtworks
● Software Engineer for 12 years
● Husband
● Father
● Dog trainer
● Read more at about.me/geisonfgf
3. Functional Swift
Functional Programming by Wikipidia:
“Functional programming is a programming paradigm that treats computation as the
evaluation of mathematical functions and avoids state and mutable data". In other
words, functional programming promotes code with no side effects, no change of
value in variables. It oposes to imperative programming, which emphasizes change of
state”.
6. What this means?
● No mutable data (no side effect).
● No state (no implicit, hidden state).
Once assigned (value binding), a variable (a symbol) does not change its value.
Functional Swift
7. What this means?
● No mutable data (no side effect).
● No state (no implicit, hidden state).
Once assigned (value binding), a variable (a symbol) does not change its value.
All state is bad? No, hidden, implicit state is bad.
Functional Swift
8. What this means?
● No mutable data (no side effect).
● No state (no implicit, hidden state).
Once assigned (value binding), a variable (a symbol) does not change its value.
All state is bad? No, hidden, implicit state is bad.
Functional programming do not eliminate state, it just make it visible and explicit (at least when programmers
want it to be).
Functional Swift
9. What this means?
● No mutable data (no side effect).
● No state (no implicit, hidden state).
Once assigned (value binding), a variable (a symbol) does not change its value.
All state is bad? No, hidden, implicit state is bad.
Functional programming do not eliminate state, it just make it visible and explicit (at least when programmers
want it to be).
● Functions are pure functions in the mathematical sense: their output depend only in their inputs, there is
not “environment”.
Functional Swift
10. What this means?
● No mutable data (no side effect).
● No state (no implicit, hidden state).
Once assigned (value binding), a variable (a symbol) does not change its value.
All state is bad? No, hidden, implicit state is bad.
Functional programming do not eliminate state, it just make it visible and explicit (at least when programmers
want it to be).
● Functions are pure functions in the mathematical sense: their output depend only in their inputs, there is
not “environment”.
● Same result returned by functions called with the same inputs.
Functional Swift
12. What are the advantages?
● Cleaner code: "variables" are not modified once defined, so we don't have to follow the change of state
to comprehend what a function, a, method, a class, a whole project works.
Functional Swift
13. What are the advantages?
● Cleaner code: "variables" are not modified once defined, so we don't have to follow the change of state
to comprehend what a function, a, method, a class, a whole project works.
● Referential transparency: Expressions can be replaced by its values. If we call a function with the same
parameters, we know for sure the output will be the same (there is no state anywhere that would
change it).
Functional Swift
14. What are the advantages?
● Cleaner code: "variables" are not modified once defined, so we don't have to follow the change of state
to comprehend what a function, a, method, a class, a whole project works.
● Referential transparency: Expressions can be replaced by its values. If we call a function with the same
parameters, we know for sure the output will be the same (there is no state anywhere that would
change it).
There is a reason for which Einstein defined insanity as "doing the same thing over and over again and
expecting different results".
Functional Swift
16. Advantages enabled by referential transparency
● Memoization
○ Cache results for previous function calls.
Functional Swift
17. Advantages enabled by referential transparency
● Memoization
○ Cache results for previous function calls.
● Idempotence
○ Same results regardless how many times you call a function.
Functional Swift
18. Advantages enabled by referential transparency
● Memoization
○ Cache results for previous function calls.
● Idempotence
○ Same results regardless how many times you call a function.
● Modularization
○ We have no state that pervades the whole code, so we build our project with small, black boxes
that we tie together, so it promotes bottom-up programming.
Functional Swift
19. Advantages enabled by referential transparency
● Memoization
○ Cache results for previous function calls.
● Idempotence
○ Same results regardless how many times you call a function.
● Modularization
○ We have no state that pervades the whole code, so we build our project with small, black boxes
that we tie together, so it promotes bottom-up programming.
● Ease of debugging
○ Functions are isolated, they only depend on their input and their output, so they are very easy to
debug.
Functional Swift
20. Advantages enabled by referential transparency
● Parallelization
○ Functions calls are independent.
○ We can parallelize in different process/CPUs/computers/…
Functional Swift
21. Advantages enabled by referential transparency
● Parallelization
○ Functions calls are independent.
○ We can parallelize in different process/CPUs/computers/…
We can execute func1 and func2 in parallel because a won’t be modified.
let result = func1(a, b) + func2(a, c)
Functional Swift
22. Advantages enabled by referential transparency
● Concurrence
a. With no shared data, concurrence gets a lot simpler:
i. No semaphores.
ii. No monitors.
iii. No locks.
iv. No race-conditions.
v. No dead-locks.
Functional Swift
25. Immutable Objects
● An OO pattern that was originated in FP world.
● When changing a data structure, don’t modify in place but create a new object.
Functional Swift
26. Immutable Objects
● An OO pattern that was originated in FP world.
● When changing a data structure, don’t modify in place but create a new object.
● Name Mutating/nonmutating method pairs consistently. A mutating method will often have a
nonmutating variant with similar semantics, but that returns a new value rather than updating an
instance in-place.
Functional Swift
27. Immutable Objects
● An OO pattern that was originated in FP world.
● When changing a data structure, don’t modify in place but create a new object.
● Name Mutating/nonmutating method pairs consistently. A mutating method will often have a
nonmutating variant with similar semantics, but that returns a new value rather than updating an
instance in-place.
○ When the operation is naturally described by a verb, use the verb’s imperative for the mutating
method and apply the “ed” or “ing” suffix to name its nonmutating counterpart.
Functional Swift
29. Don’t Update, Create - String
var name = "Geison"
var name = name + " Flores"
Functional Swift
30. Don’t Update, Create - String
var name = "Geison"
var name = name + " Flores"
let firstname = "Geison"
let lastname = "Flores"
let name = firstname + " " + lastname
Functional Swift
34. Don’t Update, Create - Dictionaries
var ages = ["John": 30]
ages["Mary"] = 28
print(ages) // ["Mary": 28, "John": 30]
Functional Swift
let johnAges = ["John": 30]
let maryAges = ["Mary": 28]
func +<Key, Value> (lhs: [Key: Value], rhs: [Key: Value]) -> [Key: Value] {
var result = lhs
rhs.forEach{ result[$0] = $1 }
return result
}
let ages = johnAges + maryAges
print(ages) // ["Mary": 28, "John": 30]
35. Higher Order Functions
Functions and methods are first-class objects in Swift, so if you want to pass a function to another function,
you can just treat it as any other object.
typealias callerType = (String, String) -> String
func caller(function: callerType) -> Void {
let result = function("Hello", "David")
print(result)
}
caller(function: { $0 + " " + $1 })
Functional Swift
36. Higher Order Functions - Map
let names = ["milu", "rantanplan"]
let namesInUppercase = names.map { $0.uppercased() }
print(namesInUppercase) //["MILU", "RANTANPLAN"]
Functional Swift
37. Higher Order Functions - Filter
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let oddNumbers = numbers.filter { $0 % 2 != 0 }
print(oddNumbers) //[1, 3, 5, 9]
Functional Swift
38. Higher Order Functions - Reduce
let numbers = [1, 2, 3, 4, 5]
let total = numbers.reduce(0, +)
print(total) //15
Functional Swift
39. Higher Order Functions - Closure
Functional Swift
func add_x(_ x: Int) -> ((Int) -> Int) {
func add_y(_ y: Int) -> Int {
return x + y
}
return add_y
}
let add_5 = add_x(5)
let add_7 = add_x(7)
print(add_5(10)) // result 15
print(add_7(10)) // result 17
print(add_x(2)(3)) // result 5
40. Currying and Partial Functions
Higher-order functions enable Currying, which the ability to take a function that accepts n parameters and turns it into a
composition of n functions each of them take 1 parameter. A direct use of currying is the Partial Functions where if you have a
function that accepts n parameters then you can generate from it one of more functions with some parameter values already
filled in.
Functional Swift
func plus(_ x: Int, _ y: Int) -> Int {
return x + y
}
func partialPlus(_ x: Int) -> ((Int) -> Int) {
func partial(_ y: Int) -> Int {
return plus(x, y)
}
return partial
}
let plus_one = partialPlus(1)
print(plus_one(5)) // 6
42. Eager vs Lazy Evaluation
● Eager evaluation: expressions are calculated at the moment that variables is assined, function called...
Functional Swift
43. Eager vs Lazy Evaluation
● Eager evaluation: expressions are calculated at the moment that variables is assined, function called...
● Lazy evaluation: delays the evaluation of the expression until it is needed.
○ Memory efficient: no memory used to store complete structures.
○ CPU efficient: no need to calculate the complete result before returning.
○ Laziness is not a requisite for FP, but it is a strategy that fits nicely on the paradigm(Haskell).
Functional Swift
44. Eager vs Lazy Evaluation
● Eager evaluation: expressions are calculated at the moment that variables is assined, function called...
● Lazy evaluation: delays the evaluation of the expression until it is needed.
○ Memory efficient: no memory used to store complete structures.
○ CPU efficient: no need to calculate the complete result before returning.
○ Laziness is not a requisite for FP, but it is a strategy that fits nicely on the paradigm(Haskell).
Swift have lazy properties and lazy collections.
Functional Swift
45. Recursion
Looping by calling a function from within itself. When you don’t have access to mutable data, recursion is used to build
up and chain data construction. This is because looping is not a functional concept, as it requires variables to be
passed around to store the state of the loop at a given time.
● Purely functional languages have no imperative for-loops, so they use recursion a lot.
● If every recursion created an stack, it would blow up very soon.
● Tail-call optimization (TCO) avoids creating a new stack when the last call in a recursion is the function itself.
Functional Swift
46. Recursion
Imperative: Functional:
Functional Swift
func fibs(_ n: Int) -> Int {
guard n != 0, n != 1 else { return n }
return fibs(n - 1) + fibs(n - 2)
}
print(fibs(6)) //8
func fibs(_ n: Int) -> Int {
var tmp = 0
var current = 0
var prev = 1
for i in 1...n {
tmp = current
current = prev
prev = tmp + current
}
return current
}
print(fibs(6)) //8
47. A Pratical Example
Exercise: "What's the sum of the first 10 natural number whose square value is divisible by 5?"
Imperative: Functional:
Functional Swift
print(
Array(1...100)
.filter({$0 * $0 % 5 == 0})
.prefix(10)
.reduce(0, +)
) //275
func main() -> Void {
var n: Int = 1
var numElements: Int = 0
var sum: Int = 0
while numElements < 10 {
if n * n % 5 == 0 {
sum += n
numElements += 1
}
n += 1
}
print(sum) //275
}
main()
49. Conclusion
● As you can see, Swift helps you write in functional style but it doesn’t force you to it.
Functional Swift
50. Conclusion
● As you can see, Swift helps you write in functional style but it doesn’t force you to it.
● Writing in functional style enhances your code and makes it more self documented. Actually it will make
it more thread-safe also.
Functional Swift
51. Conclusion
● As you can see, Swift helps you write in functional style but it doesn’t force you to it.
● Writing in functional style enhances your code and makes it more self documented. Actually it will make
it more thread-safe also.
● The main support for FP in Swift comes from the use of closures, pattern matching, lazy evaluation and
generics.
Functional Swift
52. The last advice
Learn at least one functional language, it will open your mind to a new paradigm becoming you a better
programmer.
Some Functional Languages:
● Haskell
● ML (Standard ML, Objective Caml, ...)
● Scheme
● Erlang
● Scala
● Closure
● F# learnyouahaskell.com
Functional Swift