Professional Documents
Culture Documents
2
Programming paradigm
Procedural languages
Cobol, Fortran, Basic, C
they describe, step by step, the procedure solve a
specific problem
Object-oriented programming
Smalltalk, C++, Obj-C, C#, Java, Swift.
Data and methods to manipulate it are kept as one
unit called an object.
The inner workings of an object may be changed
without affecting any code that uses the object.
Functional Programming
Haskell, Mercury, Clean - pure functional languages
Scala, Clojure, F#, - impure ones.
3
Functional Programming
Declarative programming
programming is done with expressions or
declarations instead of statements.
Pure functions (without side effects)
The output value of a function depends only on the
arguments that are passed to the function
so calling a function f twice with the same value for an
argument x produces the same result f(x) each time;
in contrast to procedures depending on a local or global
state.
No side effects, i.e., changes in state that do not
depend on the function inputs.
4
Immutable state
In a simple system, a mutable state is not problematic.
But in a large OOP system, a mutable state can produce many
headaches.
For instance, when two or more threads access the same
variable concurrently, they may modify or access it out of
order, leading to unexpected behavior.
This includes race conditions, dead locks and many other
problems.
Imagine if you could write code where the state never
mutated.
A whole issues that occur in concurrent systems would simply
vanish.
Can do this by creating an immutable property
data that is not allowed to change over the course of a program.
5
Functions as first-class objects
we can assign functions to variables,
pass them as function parameters,
return them from other functions and
do all other forms of data manipulation usually
reserved for objects.
func bar() {
print("foo")
}
let baz = bar
baz() // prints "foo"
See how we passed that function just like any other object
6
Functions in an array
func foo() { print("foo") }
For example:
func countUp(currentCount: Int) -> Int {
return currentCount + 1
}
is a pure function.
var counter = 0
func countUp() -> Int{
counter += 1
return counter
}
is not a pure function.
9
Advantage of pure function
It makes the code extremely testable.
Can save a lot of time since they make debugging
easier.
Good for parallel programming since each new call
is depended only on the variables it created itself;
thus avoiding all of the parallel/concurrent programming
pitfalls
No synchronization issues.
10
Higher order functions
Functions which take other functions as
arguments and/or return other functions as a
result.
This simple concept lies at the core of
functional programming.
It enables us to create very useful abstractions
and deal with the specifics during the call to
the function
greatly reducing code doubling.
11
Example - remove all elements from a sequence/array that are
smaller than a certain number
12
Then later on another requirement - remove all the
elements that are larger than a certain number
13
Now, we have a lot of code doubling.
Both times we need to go through a couple of
steps:
Create a new sequence
Iterate over items
Check the condition and append if its fulfilled
Return the sequence
So how could higher-order functions help us?
14
Create a single function which can take a condition as a
parameter and filter out a sequence of integers in any way
func filter(sequence: [Int], condition: (Int)->Bool) -> [Int] {
var newSequence = [Int]()
for item in sequence {
if condition(item) {
newSequence.append(item)
}
}
return newSequence
}
15
common higher-order functions in
Swift
filter
map
reduce.
16
filter
Use filter to loop over a collection and return an Array
containing only those elements that match an include
condition.
It has a single argument that specifies the include condition.
This is a closure(or function) that takes as an argument the
element from the collection and must return a Bool indicating if
the item should be included in the result.
filter applies
the input function to each element of the calling array
returns another array that has only the array elements for which
the parameter function returns true.
17
filter
18
map
Use map to loop over a collection and apply
the same operation to each element in the
collection.
The map function returns an array containing
the results of applying a mapping or transform
function to each item:
let values = [2.0,4.0,5.0,7.0]
let squares = values.map {$0 * $0}
// [4.0, 16.0, 25.0, 49.0]
19
map
20
syntax
Writing the mapping function in long form can make it easier
to see what is happening:
let values = [2.0,4.0,5.0,7.0]
let squares2 = values.map({ (value: Double) -> Double in
return value * value })
The closure has a single argument: (value: Double) and
returns a Double -> Swift can infer this.
map has a single argument which is a closure we do not need
the brackets - ( and )
with a single line closure we can even omit the return:
let squares2 = values.map {value in value * value}
22
reduce
To combine all items in a collection to create a single value.
Takes two values, an initial value and a combine closure.
to add the values of an array to an initial value of 10.0:
let items = [2.0,4.0,5.0,7.0]
let total = items.reduce(10.0,combine: +) // 28.0
24
FlatMap
To flatten a collection of collections.
let collections = [[5,2,7],[4,8],[9,1,3]]
let flat = collections.flatMap { $0 } // [5, 2, 7, 4, 8, 9, 1, 3]
26
Advantages of FP
By taking a functional approach, code can be
more concise and clear.
Also, your code will be easier to test when
isolated into modular functions that are free
from side effects.
As multi-processing cores become the norm for
both CPUs and GPUs
minimizing side effects and issues from concurrency
will become increasingly important
FP will one of the most important ways to
achieve smooth performance!
27
Use it only when needed
Functional programming is a great way to
improve the readability and testability of your
code.
But remember - its not a one-size-fits-all
paradigm.
In fact, no paradigm is.
So use it when you need it
and combine it with other features in Swift to
make better software.
28
FP vs OOP
FP OOP
Fundamental unit function Object
of abstraction
29
Mixing OOP and FP
OOP fits perfectly with FP when our objects are as
immutable as possible.
To make our objects as immutable as possible, we can
consider the following principles:
Objects should be types that encapsulate related pieces of data.
Objects can have methods; however, these methods shouldn't
change the object and should instead return a new one of the
appropriate type.
All the required state data should be injected into the class's
initialization so that it will be ready to use immediately.
Static methods can be used freely and static variables should be
avoided.
Protocols and generics should be used to avoid code duplicates.
30
OOP and FP can be used together.
Objects are closures with multiple methods, closures are
objects with a single method.
Swift supports OOP and FP.
Cocoa and Cocoa Touch frameworks that are OOP based
A great place to start working with FP techniques is
Model layer, ViewModel layer, and business logic.