Slide 1

Slide 1 text

Thanks! http://bit.ly/AltConf2017

Slide 2

Slide 2 text

This presentation doesn't contain any confidential information and isn’t intended only for anyone who knows anything. Any other distribution, re-transmission, copying or disclosure of this message is highly encouraged. If you have received this transmission in error, just take a few deep breaths and relax, it’s really not a big deal. If you like it, pass it on, if you don’t like it, pass it on. Thanks! What the Swiftly Func? ALTCONF 2017 Presentation Created For Anyone Who Will Listen! Created By James Majors, iOS Developer http://bit.ly/AltConf2017

Slide 3

Slide 3 text

func iAm(_ who: Person?) -> Details { typealias Details = String guard let me = who else { return “Not Me!” } let whatIDo = “-> iOS Developer ” let atWhere = “@ POSSIBLE Mobile” return “\(me) \(whatIDo) \(atWhere)” } typealias Person = String let whoIAm: Person? = iAm(“James Majors”) // James Majors -> iOS Developer @ POSSIBLE Mobile

Slide 4

Slide 4 text

What the Swiftly Func? http://bit.ly/AltConf2017

Slide 5

Slide 5 text

Everything Old is New Again, for now… http://bit.ly/AltConf2017

Slide 6

Slide 6 text

What is Functional Programming*? (and how to use it in Swift) *FP from now on…

Slide 7

Slide 7 text

“A monad is a monoid in the category of endofunctors”

Slide 8

Slide 8 text

“A monad is a monoid in the category of endofunctors” http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html

Slide 9

Slide 9 text

Functional Programming Topics • Airity • Partial Application • Idempotent • Functor • Lift • Referential Transparency • Lambda Calculus • Monoid • Monad • Applicative Functor • Semigroup • Setoid https://github.com/hemanth/functional-programming-jargon utm_source=hashnode.com

Slide 10

Slide 10 text

What’s Coming Up? • Simple Definition(s) • Differences between other Approaches • Explain what some of the terms mean • Example of a ‘Functional’ Drawing Engine http://bit.ly/AltConf2017

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

FP is just another TOOL in the tool box http://bit.ly/AltConf2017

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

• Side-Effect Free • Stateless • Immutable (the Data anyway) Functional Programming (FP) An approach that Strives to be… http://bit.ly/AltConf2017

Slide 17

Slide 17 text

Programming Paradigms http://bit.ly/AltConf2017

Slide 18

Slide 18 text

Programming Approaches http://bit.ly/AltConf2017

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Object-Oriented Programming • Basic Building Block = Object (variables + functions) class SomeClass: NSObject { var aProperty: String func doSomething() { /* Transform ‘aProperty’ */ } } • Uses LOCAL variables (state) • Changing variables (mutable data) changes state • Side-Effects are usually how things get done class SomeClass: NSObject { var aProperty: String func doSomething() { /* Transform ‘aProperty’ */ } }

Slide 21

Slide 21 text

OK Side Effect Mutate Data Change State When you think of… A Button on a Screen Object

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Functional Programming • Basic Building Block = Function (stateless) func function(value: Type) -> Type { let newValue = /* Transform ‘value’ */ return newValue } • Values (state) are passed INTO the Function • State is represented by immutable data • Side-Effects are don’t happen (Highly discouraged) func function(value: Type) -> Type { let newValue = /* Transform ‘value’ */ return newValue }

Slide 24

Slide 24 text

+ 2 2 = 4 Side Effect Mutate Data Change State When you think of… Adding two numbers Function

Slide 25

Slide 25 text

What is a Function http://bit.ly/AltConf2017

Slide 26

Slide 26 text

Function Input Output ‘Pure’ Function

Slide 27

Slide 27 text

func squareANumber(x: Int) -> Int { return x * x } let squareANumber = { (x: Int) in x * x } Function: Closure Expression: Closure Expression

Slide 28

Slide 28 text

func squareANumber(x: Int) -> Int { return x * x } let squareANumber = { (x: Int) in x * x } Function: Closure Expression: Function Literal

Slide 29

Slide 29 text

Closure: Function with out a name a.k.a. Anonymous Function Function: Closure with a name

Slide 30

Slide 30 text

Closure Anonymous Function Block Inline Function Lambda Expression

Slide 31

Slide 31 text

Side-Effect Free http://bit.ly/AltConf2017

Slide 32

Slide 32 text

Functional Function Input Output ‘Pure’ Function

Slide 33

Slide 33 text

OOP Function Input

Slide 34

Slide 34 text

OOP Function Input OBJ

Slide 35

Slide 35 text

OOP Function Input OBJ OBJ OBJ OBJ OBJ OBJ OBJ OBJ

Slide 36

Slide 36 text

OOP Function Input Output OBJ OBJ OBJ OBJ OBJ OBJ OBJ OBJ

Slide 37

Slide 37 text

‘add’ Function Input 4 Output (2, 2) func add(_ lhs: Int, _ rhs: Int) -> Int add(2, 2)

Slide 38

Slide 38 text

State or the lack thereof… http://bit.ly/AltConf2017

Slide 39

Slide 39 text

The value of ALL VARIABLES in an Object* at any instant in time http://bit.ly/AltConf2017

Slide 40

Slide 40 text

class ShapeClass { var shape: Shape var lineColor: Color var fillColor: Color } 3 Choices 3 Choices 3 Choices 27 POSSIBLE STATES

Slide 41

Slide 41 text

OBJ OBJ OBJ OBJ OBJ OBJ OBJ OBJ

Slide 42

Slide 42 text

Non-Mutable Data http://bit.ly/AltConf2017

Slide 43

Slide 43 text

Once a value is set, it CAN NOT be changed. http://bit.ly/AltConf2017

Slide 44

Slide 44 text

var value: Int = 10 value = 30 value = 50

Slide 45

Slide 45 text

let value: Int = 10

Slide 46

Slide 46 text

Want to change it? http://bit.ly/AltConf2017

Slide 47

Slide 47 text

Want to change it? Make a new one… http://bit.ly/AltConf2017

Slide 48

Slide 48 text

let numbersArray: [Int] init(numbers: [Int]) { numbersArray = numbers } func add(number: Int) -> NumbersStruct { var newArray = Array(numbersArray) newArray.append(number) return NumbersStruct(numbers: newArray) } struct NumbersStruct { } }

Slide 49

Slide 49 text

Value Types not References Type http://bit.ly/AltConf2017

Slide 50

Slide 50 text

Value

Slide 51

Slide 51 text

Reference

Slide 52

Slide 52 text

Value: Swift Types enum struct class Array Dictionary Reference: func

Slide 53

Slide 53 text

• Side-Effect Free • Stateless • Uses Immutable Data Functional Programming (FP) More or less(ish) http://bit.ly/AltConf2017

Slide 54

Slide 54 text

Functions as ‘First-Class’ Type http://bit.ly/AltConf2017

Slide 55

Slide 55 text

func squareANumber(x: Int) -> Int { return x * x } let squareAnInt = { (x: Int) in x * x } let squareInt = squareAnInt Type: Closure Type: Closure let aNumber = 25

Slide 56

Slide 56 text

func squareANumber(x: Int) -> Int { return x * x } func doSomething(x: Int, function: ((Int) -> Int)) -> Int { -> Int { Type: Closure Type: func doubleANumber(x: Int) -> Int { return x + x } } return function(x) Type: Apply Function to ‘x’

Slide 57

Slide 57 text

func squareANumber(x: Int) -> Int { return x * x } func doSomething(x: Int, function: ((Int) -> Int)) -> Int { -> Int { func doubleANumber(x: Int) -> Int { return x + x } } return function(x) doSomething(x: 10, function: squareANumber) // 100

Slide 58

Slide 58 text

func squareANumber(x: Int) -> Int { return x * x } func doSomething(x: Int, function: ((Int) -> Int)) -> Int { -> Int { func doubleANumber(x: Int) -> Int { return x + x } } return function(x) doSomething(x: 10, function: squareANumber) // 100 doSomething(x: 10, function: doubleANumber) // 20

Slide 59

Slide 59 text

func doSomething(x: Int, function: ((Int) -> Int)) -> Int { Type: } return function(x) Type: Type: Closure

Slide 60

Slide 60 text

} x * x func doSomething(x: Int, function: ((Int) -> Int)) -> Int { Type: Closure Type: } return function(x) let doSomething(x: 10 { (x: Int) in ) , function: Type: Type: Closure return func squareANumber(x: Int) -> Int { return x * x } doSomething(x: 10, function: squareANumber)

Slide 61

Slide 61 text

} x * x func doSomething(x: Int, function: ((Int) -> Int)) -> Int { Type: } return function(x) let doSomething(x: 10 { (x: Int) in ) Type: Type: Closure return func squareANumber(x: Int) -> Int { return x * x } doSomething(x: 10, function: squareANumber)

Slide 62

Slide 62 text

} x * x func doSomething(x: Int, function: ((Int) -> Int)) -> Int { Type: } return function(x) let doSomething(x: 10 { (x: Int) in ) Type: Type: Closure func squareANumber(x: Int) -> Int { return x * x } doSomething(x: 10, function: squareANumber)

Slide 63

Slide 63 text

} x * x func doSomething(x: Int, function: ((Int) -> Int)) -> Int { Type: } return function(x) let doSomething(x: 10 // = 100 { (x: Int) in ) Type: Type: Closure Trailing Closure Syntax func squareANumber(x: Int) -> Int { return x * x } doSomething(x: 10, function: squareANumber)

Slide 64

Slide 64 text

func doWhat(x: Int) -> ((Int) -> Int) { Type: Closure Type: } doWhat

Slide 65

Slide 65 text

func squareANumber(x: Int) -> Int { return x * x } func doWhat(x: Int) -> ((Int) -> Int) { func doubleANumber(x: Int) -> Int { return x + x } } Inner Functions doWhat

Slide 66

Slide 66 text

func squareANumber(x: Int) -> Int { return x * x } func doWhat(x: Int) -> ((Int) -> Int) { func doubleANumber(x: Int) -> Int { return x + x } } if x % 2 == 0 { return squareANumber } else { return doubleANumber } doWhat squareANumber doubleANumber

Slide 67

Slide 67 text

func doWhat(x: Int) -> ((Int) -> Int) { } if x % 2 == 0 { return squareANumber } else { return doubleANumber } let squareANumber = { (x: Int) in x * x } let doubleANumber = { (x: Int) in x + x } doWhat { (x: Int) in x + x } { (x: Int) in x * x } squareANumber doubleANumber

Slide 68

Slide 68 text

squareIt(5) // = 25 func doWhat(x: Int) -> ((Int) -> Int) { } if x % 2 == 0 { return squareANumber } else { return doubleANumber } let squareIt = doWhat(x: 2) let doubleIt = doWhat(x: 3) doubleIt(5) // = 10 doWhat { (x: Int) in x + x } { (x: Int) in x * x }

Slide 69

Slide 69 text

Function take a Function as an argument Function return a Function Closure Closure http://bit.ly/AltConf2017

Slide 70

Slide 70 text

Higher-Order Functions http://bit.ly/AltConf2017

Slide 71

Slide 71 text

Higher-Order Functions Function that takes a Function as an argument Function that returns a Function Function that takes and returns a Function

Slide 72

Slide 72 text

IntFunc func takeFunction(x: Int, function: return function(x) } func returnFunction(x: Int) -> if x % 2 == 0 { return { (x: Int) in x + x } } else { return { (x: Int) in x * x } } } typealias IntFunc = (Int) -> Int ) -> Int { { ((Int) -> Int)

Slide 73

Slide 73 text

IntFunc func takeFunction(x: Int, function: return function(x) } func returnFunction(x: Int) -> if x % 2 == 0 { return { (x: Int) in x + x } } else { return { (x: Int) in x * x } } } typealias IntFunc = (Int) -> Int ) -> Int { { IntFunc

Slide 74

Slide 74 text

Map http://bit.ly/AltConf2017

Slide 75

Slide 75 text

Map func map( function: (T) -> U) -> [U]

Slide 76

Slide 76 text

Map func map( function: (T) -> U) -> [U] let new = [1,2,3,4,5].map { 10 * $0 }

Slide 77

Slide 77 text

Function [Array] [Results] { 10 * number } { 10 * number } { 10 * number } { 10 * number } { 10 * } { 10 * } { 10 * } { 10 * } { 10 * } 1 2 3 4 5 [ , , , , ]

Slide 78

Slide 78 text

Function [Array] [Results] 10 { 10 * number } { 10 * number } { 10 * number } { 10 * number } { 10 * } { 10 * } { 10 * } { 10 * } { 10 * } = 1 2 3 4 5 [ , , , , ]

Slide 79

Slide 79 text

Function [Array] [Results] 10 { 10 * } { 10 * } { 10 * } { 10 * } { 10 * } = 20 = 30 = 40 = 50 = 1 2 3 4 5 [ , , , , ] 10 20 30 40 50

Slide 80

Slide 80 text

Map func map( function: (T) -> U) -> [U] ‘Generic’ Types

Slide 81

Slide 81 text

Map func map( function: (T) -> U) -> [U] let new = [1,2,3,4,5].map { 10 * $0 } Positional Argument (i.e. Function’s first Argument)

Slide 82

Slide 82 text

Map func map( function: (T) -> U) -> [U] let new = [1,2,3,4,5].map { 10 * $0 } // new = [10,20,30,40,50]

Slide 83

Slide 83 text

Generic Types

Slide 84

Slide 84 text

func map(function: (T) -> U) -> [U] Generic Types

Slide 85

Slide 85 text

func map(function: (InputType) -> U) -> [U] Generic Types

Slide 86

Slide 86 text

func map(function: (T) -> OutputType) -> [OutputType] Generic Types

Slide 87

Slide 87 text

func map(function: (InputType) -> OutputType) -> [OutputType] Generic Types

Slide 88

Slide 88 text

func map(function: (AType) -> BType) -> [BType] Generic Types

Slide 89

Slide 89 text

func map(function: (Int) -> U) -> [U] Generic Types

Slide 90

Slide 90 text

func map(function: (Int) -> Int) -> [Int] Generic Types

Slide 91

Slide 91 text

func map(function: (Int) -> String) -> [String] Generic Types

Slide 92

Slide 92 text

func map(function: (String) -> Int) -> [Int] Generic Types

Slide 93

Slide 93 text

func map(function: (T) -> U) -> [U] Generic Types

Slide 94

Slide 94 text

T = Some Type func map(function: (T) -> U) -> [U] Int, Float, String, class, struct… Generic Types

Slide 95

Slide 95 text

T = Some Type U = Some Type func map(function: (T) -> U) -> [U] Int, Float, String, class, struct… Int, Float, String, class, struct… Generic Types

Slide 96

Slide 96 text

Filter http://bit.ly/AltConf2017

Slide 97

Slide 97 text

Filter func filter(function: (T) -> Bool) -> [T] let new = [1,2,3,4,5].filter { $0 % 2 == 0 }

Slide 98

Slide 98 text

Function [Array] [Results] { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } 1 2 3 4 5 [ , ]

Slide 99

Slide 99 text

Function [Array] [Results] { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } 2 3 4 5 [ , ] 1

Slide 100

Slide 100 text

Function [Array] [Results] false { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } = 2 3 4 5 [ , ] 1

Slide 101

Slide 101 text

Function [Array] [Results] { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } 2 3 4 5 [ , ]

Slide 102

Slide 102 text

Function [Array] [Results] { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } 3 4 5 [ , ] 2

Slide 103

Slide 103 text

Function [Array] [Results] { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } { x % 2 == 0 } true = 3 4 5 [ , ] 2

Slide 104

Slide 104 text

Function [Array] [Results] [ , ] 2 4 2 4

Slide 105

Slide 105 text

Filter

Slide 106

Slide 106 text

Filter func filter(function: (T) -> Bool) -> [T]

Slide 107

Slide 107 text

Filter let new = [1,2,3,4,5].filter { $0 % 2 == 0 } func filter(function: (T) -> Bool) -> [T]

Slide 108

Slide 108 text

Filter let new = [1,2,3,4,5].filter { $0 % 2 == 0 } // new = [2,4] func filter(function: (T) -> Bool) -> [T]

Slide 109

Slide 109 text

Reduce http://bit.ly/AltConf2017

Slide 110

Slide 110 text

Reduce

Slide 111

Slide 111 text

Reduce func reduce( initialValue: T, function: (T, T) -> T) -> T

Slide 112

Slide 112 text

{ $0 + $1 } Reduce func reduce( initialValue: T, function: (T, T) -> T) -> T let new = [1,2,3,4,5].reduce(0, + )

Slide 113

Slide 113 text

{ $0 + $1 } Reduce func reduce( initialValue: T, function: (T, T) -> T) -> T let new = [1,2,3,4,5].reduce(0, + ) Acc. Acc.

Slide 114

Slide 114 text

{ $0 + $1 } Reduce func reduce( initialValue: T, function: (T, T) -> T) -> T let new = [1,2,3,4,5].reduce(0, + ) [Element] Acc. [Element] Acc.

Slide 115

Slide 115 text

{ $0 + $1 } Reduce func reduce( initialValue: T, function: (T, T) -> T) -> T let new = [1,2,3,4,5].reduce(0, + )

Slide 116

Slide 116 text

Reduce func reduce( initialValue: T, function: (T, T) -> T) -> T let new = [1,2,3,4,5].reduce(0, + )

Slide 117

Slide 117 text

Result [ , , , , ] 1 2 3 4 5 Function [Array] Accumulator Initial Value + } { x acc Acc Init

Slide 118

Slide 118 text

Result [ , , , , ] 1 2 3 4 5 Function [Array] + } { x acc Acc Init =

Slide 119

Slide 119 text

Result [ , , , , ] 1 2 3 4 5 Function [Array] + } { x acc = 0 0

Slide 120

Slide 120 text

Result + } 1 2 3 4 5 Function [Array] { x acc + } { x acc 0

Slide 121

Slide 121 text

Result + } 1 2 3 4 5 Function [Array] { = 1 0

Slide 122

Slide 122 text

{ $0 + $1 } Reduce func reduce( initialValue: T, function: (T, T) -> T) -> T let new = [1,2,3,4,5].reduce(0, + ) [Element] Acc. [Element] Acc.

Slide 123

Slide 123 text

Reduce func reduce( initialValue: T, function: (T, T) -> T) -> T let new = [1,2,3,4,5].reduce(0, + ) // new = 15

Slide 124

Slide 124 text

Imperative vs. Declarative ‘How To Do Something’ vs. ‘What You Want Done’ http://bit.ly/AltConf2017

Slide 125

Slide 125 text

Imperative Programming describes the algorithm http://bit.ly/AltConf2017

Slide 126

Slide 126 text

func arrayTimesTen(array: [Int]) -> [Int] { var outputArray = [Int]() for number in array { var newNumber = number * 10 outputArray.append(newNumber) } return outputArray } var outputArray = [Int]() for number in array { var newNumber = number * 10 outputArray.append(newNumber) } let newNumber = number * 10 outputArray.append(newNumber) return outputArray number * 10

Slide 127

Slide 127 text

func arrayTimesTen(array: [Int]) -> [Int] { var outputArray = [Int]() for number in array { var newNumber = number * 10 outputArray.append(newNumber) } return outputArray } var outputArray = [Int]() for number in array { var newNumber = number * 10 outputArray.append(newNumber) } let newNumber = number * 10 outputArray.append(newNumber) return outputArray number * 10

Slide 128

Slide 128 text

Declarative Programming describes the result http://bit.ly/AltConf2017

Slide 129

Slide 129 text

let mapped = array.map { $0 * 10 } let array = [1,2,3,4,5]

Slide 130

Slide 130 text

let mapped = array.map { $0 * 10 } let filtered = array.filter { $0 % 2 == 0 } let array = [1,2,3,4,5]

Slide 131

Slide 131 text

let mapped = array.map { $0 * 10 } let filtered = array.filter { $0 % 2 == 0 } let array = [1,2,3,4,5]

Slide 132

Slide 132 text

let mapped = array.map { $0 * 10 } let filtered = array.filter { $0 % 2 == 0 } let reduced = array.reduce(0, + ) let array = [1,2,3,4,5]

Slide 133

Slide 133 text

let mapped = array.map { $0 * 10 } let filtered = array.filter { $0 % 2 == 0 } let reduced = array.reduce(0, + ) let array = [1,2,3,4,5]

Slide 134

Slide 134 text

let mapIt = [1,2,3,4,5].map(timesTen) func timesTen(x: Int) -> Int { return x * 10 }

Slide 135

Slide 135 text

let mapIt = [1,2,3,4,5].map(timesTen) let filterIt = [1,2,3,4,5].filter(isEven) func timesTen(x: Int) -> Int { return x * 10 } func isEven(x: Int) -> Bool { return x % 2 == 0 }

Slide 136

Slide 136 text

let mapIt = [1,2,3,4,5].map(timesTen) let filterIt = [1,2,3,4,5].filter(isEven) func timesTen(x: Int) -> Int { return x * 10 } func isEven(x: Int) -> Bool { return x % 2 == 0 } let addIt = [1,2,3,4,5].reduce(0, add) func add(x: Int, y: Int) -> Int { return x + y }

Slide 137

Slide 137 text

Currying http://bit.ly/AltConf2017

Slide 138

Slide 138 text

‘Partial Application’ of a Function http://bit.ly/AltConf2017

Slide 139

Slide 139 text

of a Function ‘Initialization’ http://bit.ly/AltConf2017

Slide 140

Slide 140 text

func addClosure(x: Int) -> ((Int) -> Int) { return { y in x * y } } let add = addClosure(x: 10) add(10) // 100 x x

Slide 141

Slide 141 text

func addClosure(x: Int) -> ((Int) -> Int) { return { y in x * y } } let add = addClosure(x: 10) add(100) // 1000 add(10) // 100 x x

Slide 142

Slide 142 text

((col or: Color) -> DrawingItem) func itemWith(shape: Shape, color: Color) -> DrawingItem { return DrawingItem(shape: shape, color: color) } func someShape(shape: Shape) -> } (_ color: Color) -> DrawingItem { return { color in return itemWith(shape: shape, color: color) } shape color shape color { } let ovalShape = someShape(shape: .oval) let triangleShape = someShape(shape: .triangle) let blackOval = ovalShape(.black) let whiteTriangle = triangleShape(.white) return itemWith(shape: shape, color: color) itemWith

Slide 143

Slide 143 text

Functional Drawing Engine http://bit.ly/AltConf2017

Slide 144

Slide 144 text

Go forth and be Func’y! http://bit.ly/AltConf2017

Slide 145

Slide 145 text

This presentation doesn't contain any confidential information and isn’t intended only for anyone who knows anything. Any other distribution, re-transmission, copying or disclosure of this message is highly encouraged. If you have received this transmission in error, just take a few deep breaths and relax, it’s really not a big deal. If you like it, pass it on, if you don’t like it, pass it on. Thanks! What the Swiftly Func? ALTCONF 2017 Presentation Created For Anyone Who Will Listen! Created By James Majors, iOS Developer http://bit.ly/AltConf2016

Slide 146

Slide 146 text

Thanks! http://bit.ly/AltConf2017