Slide 1

Slide 1 text

Func%onal)Swi- An#Introduc+on ©"Farley"Caesar,"2015 1

Slide 2

Slide 2 text

Agenda * Your Speaker * What is Functional Programming? * Why Functional? Why Functional in Swift? * Key Aspects of a Functional Approach * Your Functional Tool Box * Swift Value Types vs Reference Types * Application Architecture * Your Advanced Functional Tool Box * Next Steps v1.0%(March%2015) ©"Farley"Caesar,"2015 2

Slide 3

Slide 3 text

Speaker:(Farley(Caesar • Programming*since*the*early*80's • BSc.*in*Computer*Science*from*the* University*of*Toronto • Programming*professionally*since*1997* (Bell*Sygma,*IBM) • Programming*on*iOS*since*2011 ©"Farley"Caesar,"2015 3

Slide 4

Slide 4 text

struct Speaker { let identifyingTraits: [String:String] let languagesTimeline: [String] let languagesUsedInAnger: [String] let currentLanguageOfChoice: String } ©"Farley"Caesar,"2015 4

Slide 5

Slide 5 text

let identifyingTraits = ["Name" : "Farley Caesar", "Title" : "Solution Architect", "Company" : "Royal Bank of Canada", "Interests" : "Coding, Basketball", "Twitter" : "@publicfarley", "email" : "[email protected]", "blog" : "http://farley.tumblr.com", "LinkedIn" : "Farley Caesar"] ©"Farley"Caesar,"2015 5

Slide 6

Slide 6 text

let languagesTimeline = ["AppleSoft Basic", "6502 Assembler", "Pascal", "Ada", "COBOL", "Prolog", "Lisp", "Object Oriented Turing", "C", "C++", "Java", "Groovy", "Clojure", "Ruby", "Objective-C", "Swift"] ©"Farley"Caesar,"2015 6

Slide 7

Slide 7 text

let languagesUsedExtensivelyAndOfCourseInAnger = ["C", "C++", "Java", "Groovy", "Clojure", "Objective-C"] ©"Farley"Caesar,"2015 7

Slide 8

Slide 8 text

let currentLanguageOfChoice = "Swift" var farleyCaesar = Speaker( identifyingTraits: identifyingTraits, languagesTimeline: languagesTimeline, languagesUsedInAnger: languagesUsedExtensivelyAndOfCourseInAnger, currentLanguageOfChoice: currentLanguageOfChoice) ©"Farley"Caesar,"2015 8

Slide 9

Slide 9 text

Survey'Time Show%of%hands... • Familiar(with:( • Swi.? • Func3onal(Programming? • A(Func3onal(Language: • Haskell,(F#,(Scala,(Clojure? ©"Farley"Caesar,"2015 9

Slide 10

Slide 10 text

A"couple"more"survey"ques/ons Given&the&event&Apple&just&had.. ©"Farley"Caesar,"2015 10

Slide 11

Slide 11 text

Who's&ge)ng&this? ©"Farley"Caesar,"2015 11

Slide 12

Slide 12 text

or#this? ©"Farley"Caesar,"2015 12

Slide 13

Slide 13 text

or#this? ©"Farley"Caesar,"2015 13

Slide 14

Slide 14 text

? ©"Farley"Caesar,"2015 14

Slide 15

Slide 15 text

Star%ng(at($10,000! ©"Farley"Caesar,"2015 15

Slide 16

Slide 16 text

Haskell "An$advanced$purely/func1onal$ programming$language" —"h$ps://www.haskell.org/ I'm$not$here$to$talk$about$Haskell. Comic&Courtesy&XKCD:&h2p:/ /xkcd.com/1312/ ©"Farley"Caesar,"2015 16

Slide 17

Slide 17 text

.1 1"Image"source:"h/p:/ /boingboing.net/2015/01/28/a;beginners;guide;to;the;red.html ©"Farley"Caesar,"2015 17

Slide 18

Slide 18 text

What%is%Func,onal%Programming? (The$Red$Pill$Explained) Func%onal)programming)is)a)programming)paradigm...that)treats) computa%on)as)the)evalua%on)of)mathema%cal)func%ons)and) avoids)changing7state)and)mutable)data.)It)is)a)declara%ve) programming)paradigm,)which)means)programming)is)done)with) expressions. —"Wikipedia ©"Farley"Caesar,"2015 18

Slide 19

Slide 19 text

Why$Func)onal? ©"Farley"Caesar,"2015 19

Slide 20

Slide 20 text

99"Li%le"bugs"in"the"code, 99"bugs"in"the"code, 1"bug"fixed..."compile"again, 100"li%le"bugs"in"the"code. —"h$p://www.hongkiat.com/blog/programming6jokes/ ©"Farley"Caesar,"2015 20

Slide 21

Slide 21 text

Why$Func)onal? Building(applica,ons(where(func,onal( concepts(and(constructs(are(preferred,( leads(to(code(that(is(easier(to(reason( about,(more(maintainable,(and(testable.( Addi,onally,(immutable(data(coupled(with( pure(func,ons(enables(code(that(is(more( amenable(to(parallelism(and(concurrent( programming. ©"Farley"Caesar,"2015 21

Slide 22

Slide 22 text

The$Free$Lunch$is$Over!2 • The%number%of%transistors%con2nues%to% climb,%but%CPU%speed%has%plateaued. • Need%someplace%to%put%those% transistors...%Cores!% • Concurrent%programming%is%our%future. • A%func2onal%approach%to%programming% makes%concurrent%programming%simpler. 2"The"Free"Lunch"Is"Over:"A"Fundamental"Turn"Toward"Concurrency"in" So=ware">"h?p:/ /www.gotw.ca/publicaEons/concurrency>ddj.htm ©"Farley"Caesar,"2015 22

Slide 23

Slide 23 text

Quick&Aside&on&Clojure One$of$the$earliest$programming$languages$that$embodied$ func5onal$concepts$was$Lisp.$My$func5onal$weapon$of$choice,$ un5l$a$li

Slide 24

Slide 24 text

Wait%a%Second.% Backup.%Did%you% say%Lisp?? ©"Farley"Caesar,"2015 24

Slide 25

Slide 25 text

Learn&Lisp&in&1&Slide! \\ C: add(1,2); \\ Obj-C: [adder addNumber:1 toNumber:2]; ; Lisp (add 1 2) Now$you$know$Lisp! ©"Farley"Caesar,"2015 25

Slide 26

Slide 26 text

But$to$code$for$iOS$and$the$Mac,$I$had$to$use$Objec7ve9C Over%&me%I%grew%to%actually%enjoy%programming%in%Objec&ve7C.% The%introduc&on%of%new%language%features%such%as%Automa&c% Reference%Coun&ng%(ARC),%Objec&ve7C%Literals,%and%proper&es% made%it%much%more%palatable.%This%meant%s&cking%preFy%much%to% OO. Un#l.... ©"Farley"Caesar,"2015 26

Slide 27

Slide 27 text

©"Farley"Caesar,"2015 27

Slide 28

Slide 28 text

©"Farley"Caesar,"2015 28

Slide 29

Slide 29 text

©"Farley"Caesar,"2015 29

Slide 30

Slide 30 text

©"Farley"Caesar,"2015 30

Slide 31

Slide 31 text

Some%long%)me%Objec)ve/C% developers%be%like.... ©"Farley"Caesar,"2015 31

Slide 32

Slide 32 text

©"Farley"Caesar,"2015 32

Slide 33

Slide 33 text

Why$Func)onal$Swi0? ©"Farley"Caesar,"2015 33

Slide 34

Slide 34 text

'Objec've)C+without+the+C'+implies+ something+subtrac've,+but+Swi<+ drama'cally+expands+the+design+ space+through+the+introduc'on+of+ generics+and+func'onal+ programming+concepts. —"Swi&'s"creator,"Chris"La3ner ©"Farley"Caesar,"2015 34

Slide 35

Slide 35 text

Aspects'of'Func-onal • Immutable*Data*(Values) • Pure*Func5ons • Higher*Order*Func5ons • Func5ons*as*Arguments.*Func5ons*as*Return*Values ©"Farley"Caesar,"2015 35

Slide 36

Slide 36 text

Func%onal)Swi- Swi$%has%first%class%support%for%the%aforemen5oned%func5onal% aspects,%plus%a%nice%consistent%syntax%for%func5ons%and%closures. Okay, yes. But can't I do all that in Objective-C? ©"Farley"Caesar,"2015 36

Slide 37

Slide 37 text

It's%not%about%what%a% language%makes% possible,%it's%about% what%it%makes% idioma6c.% —"Rich"hickey."Creator"of"Clojure." [Paraphrased] ©"Farley"Caesar,"2015 37

Slide 38

Slide 38 text

Immutable)Data)+)Working)Defini4on A"construct"whose"data"cannot"be" changed"a1er"its"crea3on." Also%known%as%a%value. ©"Farley"Caesar,"2015 38

Slide 39

Slide 39 text

Immutable)Data?) Come)on... ©"Farley"Caesar,"2015 39

Slide 40

Slide 40 text

Immutable)Data)+)Benefits • Persistent)*)Values)can't)change)out) from)underneath)you) • Can)be)shared)without)worry • Thread)Safe)*)Values)don't)mind)many) observers • Simple)*)Whole)classes)of)concerns)go) away • Allows)avoidance)of)thinking)of)Bme) and)sequence) ©"Farley"Caesar,"2015 40

Slide 41

Slide 41 text

Immutable)Data)+)Benefits Excellent(talks(that(go(deep(into(this( subject:( • The$Value$of$Values"#"Rich"Hickey" h,p:/ /www.infoq.com/presenta;ons/Value#Values " • Controlling$Complexity$in$Swi8$or$ Making$Friends$with$Value"#"Andy" Matuschak h,p:/ /realm.io/news/andy#matuschak#controlling#complexity/ h,p:/ /www.objc.io/issue#16/swiH#classes#vs#structs.html ©"Farley"Caesar,"2015 41

Slide 42

Slide 42 text

Swi$%Value%Types%vs% Reference%Types Value&Types: • Numbers,*strings,*arrays,*dic3onaries,* enums,*tuples,*and*structs. Reference'Types: • Classes ©"Farley"Caesar,"2015 42

Slide 43

Slide 43 text

Value&Types Copied'on'assignment.'Single'Owner. ©"Farley"Caesar,"2015 43

Slide 44

Slide 44 text

Value&Types:"Int,"Float,"Bool,"String,"Array,"Dic4onary,"Structs," Enums,"Tuples,".. Example(from:(h.ps://speakerdeck.com/andymatuschak/controlling;complexity;in;swi=;or;making;friends;with;value " var a = 10 var b = a // a = 10; b = 10 b = 5 // a = 10; b = 5 ©"Farley"Caesar,"2015 44

Slide 45

Slide 45 text

Reference'Types Shared'on'assignment.'Mul3ple'Owners ©"Farley"Caesar,"2015 45

Slide 46

Slide 46 text

Reference'Types:"Classes Example(from:(h.ps://speakerdeck.com/andymatuschak/controlling;complexity;in;swi=;or;making;friends;with;value " // Objects var a = UIView() var b = a // a.alpha = 1; b.alpha = 1 b.alpha = 0 // a.alpha = 0; b.alpha = 0 ©"Farley"Caesar,"2015 46

Slide 47

Slide 47 text

Pure%Func)ons ©"Farley"Caesar,"2015 47

Slide 48

Slide 48 text

Pure%Func)ons 1. The&func+on&always&evaluates&to&the&same&result&value&given&the& same&argument&value(s).....&The&result&value&need¬&depend&on& all&(or&any)&of&the&argument&values.&However,&it&must&depend&on& nothing&other&than&the&argument&values. 2. Evalua+on&of&the&result&does¬&cause&any&seman+cally& observable&side&effect&or&output,&such&as&muta+on&of&mutable& objects&or&output&to&I/O&devices& !!"Wikipedia"(h,p:/ /en.wikipedia.org/wiki/Pure_func:on) ©"Farley"Caesar,"2015 48

Slide 49

Slide 49 text

Pure%Func)on%+%Example In#the#abstract:#y"="f(x)# For$example,$ $is$a$pure$func2on.$ For$this$func-on,$a$given$value$of$x$will$produce$the$same$y.$ Always.! It#doesn't#ma,er#how#o0en,#or#when#it#is#run.#You#will#get#the#same# output.#Square#root#has#no#side#effects#and#is#only#dependent#on#its# arguments. ©"Farley"Caesar,"2015 49

Slide 50

Slide 50 text

For$example,$in$the$Swi2$REPL... import Foundation sqrt(16.0) // => 4 ©"Farley"Caesar,"2015 50

Slide 51

Slide 51 text

Referen&al)Transparency if#y"="f(x)#and#f(x)#is#a#pure#func-on,#then#one#can#correctly#state# that#f(x)#is#a#defined#value#also#known#as#y. Can$subs(tute$the$expression$f(x)$with$y.$This$is$known$as$ Referen&al)Transparency. This%is%a%great%property%of%pure%func2ons,%that%is%tremendously% useful%for%reasoning%about%and%tes2ng%our%programs. ©"Farley"Caesar,"2015 51

Slide 52

Slide 52 text

Swi$%&%Func+on%Syntax Func%ons: // func [function name][Args] -> [Return Type] { // [Body] // } // Declaration func doubleIt(x: Int) -> (Int) { return 2 * x } // Use doubleIt(4) // => 16 ©"Farley"Caesar,"2015 52

Slide 53

Slide 53 text

Swi$%&%Closure%Syntax // Block Signature (Closure that takes no arguments and returns Void): // ()->() // eg. Closure that takes an Int and returns an Int: // (Int) -> (Int) // Closure that takes an Int and returns an Int let doubleIt: (Int)->(Int) = { (x: Int) in return 2 * x } // Use doubleIt(4) // => 16 ©"Farley"Caesar,"2015 53

Slide 54

Slide 54 text

Closures(Capture(Their(Surrounding(Scope Note,&since&closures&capture&the&values&in&their&inclosing&scope& when&declared,&they&can&be&impure. This&can&be&useful&however,&for&callbacks,&etc.&Be&aware&of&the& capture&seman=cs&however&to&avoid&circular&references.& (Capturing*self) ©"Farley"Caesar,"2015 54

Slide 55

Slide 55 text

Closure(Example: let x: Int = 5 func add5(y: Int) -> Int { return x+y } // This named closure (a function) captures the value of x at time of declaration add5(50) // => 55 // Notice how the closure can be stored and used later let functionDictionary: [String : (Int)->Int] = ["addAFiver":add5] if let anAdd5Function = functionDictionary["addAFiver"] { println(anAdd5Function(50)) } // => 55 println(functionDictionary["addAFiver"]!(50)) // => 55 ©"Farley"Caesar,"2015 55

Slide 56

Slide 56 text

Higher'Order'Func.ons'1'Func.ons'as'Arguments We're%already%used%to%this%with%comple4on%blocks.%We'll%see,%in% later%slides,%how%to%apply%this%with%more%purity%using%map,%filter,% reduce,%etc.. // Completion block example... import EventKit EKEventStore().requestAccessToEntityType(EKEntityTypeEvent, completion: { (isHasAccessToApplicationCalendar: Bool, error: NSError?) in if isHasAccessToApplicationCalendar { println("I'm in baby!") } else { let message = "Access not granted to events. " + (error?.description ?? "") println(message) } }) ©"Farley"Caesar,"2015 56

Slide 57

Slide 57 text

Higher'Order'Func.ons'1'Func.ons'as'Return'Values func greaterThanFunctionFor(n: Int) -> (Int -> Bool) { let greaterThanFunc: Int -> Bool = { m in return m > n } return greaterThanFunc } let isGreaterThan10 = greaterThanFunctionFor(10) isGreaterThan10(20) // => true isGreaterThan10(5) // => false ©"Farley"Caesar,"2015 57

Slide 58

Slide 58 text

The$future$is$a$func.on$of$the$past,$ and$doesn’t$change$it —"Rich"Hickey ©"Farley"Caesar,"2015 58

Slide 59

Slide 59 text

Your%Func)onal%Tool%Box The$"Go$to"$Trinity: • Map • Reduce • Filter ©"Farley"Caesar,"2015 59

Slide 60

Slide 60 text

MAP ───── ┌───────┬───────┬───────┬───────┐ │ ┌─┐ │ ┌─┐ │ ┌─┐ │ ┌─┐ │ │ └─┘ │ └─┘ │ └─┘ │ └─┘ │ └───────┴───────┴───────┴───────┘ │ transformation function │ ▼ ┌───────┬───────┬───────┬───────┐ │ ┌■┐ │ ┌■┐ │ ┌■┐ │ ┌■┐ │ │ └■┘ │ └■┘ │ └■┘ │ └■┘ │ └───────┴───────┴───────┴───────┘ ©"Farley"Caesar,"2015 60

Slide 61

Slide 61 text

Map$Example$for$Array Declara'on: func map(transform: (T) -> U) -> [U] Returns(a(new(array(with(the(transformClosure(applied(to(all( elements(in(the(receiver. ©"Farley"Caesar,"2015 61

Slide 62

Slide 62 text

Map$Example$for$Array Requirement: Produce)a)list)of)the)squares)of)the)first)10)posi6ve)numbers. let firstTenPositiveIntegers = [Int](1...10) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ©"Farley"Caesar,"2015 62

Slide 63

Slide 63 text

Impera've)Approach: let firstTenPositiveIntegers = [Int](1...10) var firstTenSquares = [Int]() for number in firstTenPositiveIntegers { firstTenSquares.append(number*number) } println(firstTenSquares) // => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ©"Farley"Caesar,"2015 63

Slide 64

Slide 64 text

Problems)with)the)Impera1ve)Approach: • Mixes'the'mechanism'(step'through'and'select'each'item)'with' the'policy'of'transforma9on'of'the'items.' • Not'declara9ve • Also,'what'if'now'we'do'the'following... firstTenSquares.append(23) println(firstTenSquares) => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 23] // Oops! That's not the 1st 10 squares. // Must remember to make result immutable to avoid incorrect modification. ©"Farley"Caesar,"2015 64

Slide 65

Slide 65 text

Func%onal)Approach: let firstTenPositiveIntegers = [Int](1...10) let firstTenSquares = firstTenPositiveIntegers.map {$0 * $0} println(firstTenSquares) // => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ©"Farley"Caesar,"2015 65

Slide 66

Slide 66 text

Func%onal)Approach: Some%may%find%the%following%more%readable..%YMMV. let firstTenPositiveIntegers = [Int](1...10) func squareInt(num: Int) -> Int { return num * num } let firstTenSquares = firstTenPositiveIntegers.map(squareInt) println(firstTenSquares) // => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ©"Farley"Caesar,"2015 66

Slide 67

Slide 67 text

Func%onal)Approach: Some%may%find%the%following%more%readable..%YMMV. let firstTenPositiveIntegers = [Int](1...10) let firstTenSquares = firstTenPositiveIntegers.map { number in return (number * number) } println(firstTenSquares) // => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ©"Farley"Caesar,"2015 67

Slide 68

Slide 68 text

Benefits'of'the'Func.onal'Approach: • Declara(ve.+States+what+we+want+to+do.+Not+how+we+want+to+do+ it. • Separates+the+mechanism+(step+through+and+select+each+item)+ from+the+policy+of+transforma(on+of+the+items.+ • Mechanism+nicely+encapsulated+in+map.+Policy+nicely+ encapsulated+by+{.2.*.$0.} ©"Farley"Caesar,"2015 68

Slide 69

Slide 69 text

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // | // | map (item * item) // | // ▼ [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ©"Farley"Caesar,"2015 69

Slide 70

Slide 70 text

What%if%now... firstTenSquares.append(23) /* Not gonna' be able ta' do it! => error: immutable value of type 'Array' only has mutating members named 'append' */ ©"Farley"Caesar,"2015 70

Slide 71

Slide 71 text

FILTER ────── ┌───────┬───────┬───────┬───────┐ │ ┌─┐ │ ┌─┐ │ ┌─┐ │ ┌─┐ │ │ └─┘ │ └─┘ │ └─┘ │ └─┘ │ └───────┴───────┴───────┴───────┘ │ transformation function │ ▼ ┌───────┬───────┐ │ ┌─┐ │ ┌─┐ │ │ └─┘ │ └─┘ │ └───────┴───────┘ ©"Farley"Caesar,"2015 71

Slide 72

Slide 72 text

Filter'Example'for'Array Declara'on: func filter(includeElement: (T) -> Bool) -> [T] Returns(a(new(array(containing(the(elements(of(the(original(array( for(which(a(provided(closure(indicates(a(match. ©"Farley"Caesar,"2015 72

Slide 73

Slide 73 text

Filter'Example'for'Array Requirement:" Produce"a"list"of"even"squares"of"the"first"10"posi6ve"numbers. ©"Farley"Caesar,"2015 73

Slide 74

Slide 74 text

Impera've)Approach: let firstTenPositiveIntegers = [Int](1...10) var evenSquaresInFirstTen = [Int]() for number in firstTenPositiveIntegers { let square = number * number if (square % 2) == 0 { evenSquaresInFirstTen.append(square) } } println(evenSquaresInFirstTen) // => [4, 16, 36, 64, 100] ©"Farley"Caesar,"2015 74

Slide 75

Slide 75 text

Func%onal)Approach): let firstTenPositiveIntegers = [Int](1...10) let evenSquaresInFirstTen = firstTenPositiveIntegers.map({$0 * $0}) .filter({($0 % 2) == 0}) println(evenSquaresInFirstTen) // => [4, 16, 36, 64, 100] ©"Farley"Caesar,"2015 75

Slide 76

Slide 76 text

REDUCE ────── ┌───────┬───────┬───────┬───────┐ │ ┌─┐ │ ┌─┐ │ ┌─┐ │ ┌─┐ │ │ └─┘ │ └─┘ │ └─┘ │ └─┘ │ └───────┴───────┴───────┴───────┘ │ transformation function │ ▼ ┌■┐ └■┘ ©"Farley"Caesar,"2015 76

Slide 77

Slide 77 text

Reduce&Example&for&Array Declara'on: func reduce(initial: U, combine: (U, T) -> U) -> U Returns(a(single(value(represen/ng(the(result(of(applying(a( provided(reduc/on(closure(for(each(element. ©"Farley"Caesar,"2015 77

Slide 78

Slide 78 text

Reduce&Example&for&Array&# Requirement: What&is&the&sum&of&the&even&squares&in&the&first&10&posi5ve& numbers.? ©"Farley"Caesar,"2015 78

Slide 79

Slide 79 text

Impera've)Approach: let firstTenPositiveIntegers = [Int](1...10) var sumOfEvenSquaresInFirstTen = 0 for number in firstTenPositiveIntegers { let square = number * number if (square % 2) == 0 { sumOfEvenSquaresInFirstTen += square } } println(sumOfEvenSquaresInFirstTen) // => 220 ©"Farley"Caesar,"2015 79

Slide 80

Slide 80 text

Func%onal)Approach): let firstTenPositiveIntegers = [Int](1...10) let sumOfEvenSquaresInFirstTen = firstTenPositiveIntegers.map({$0 * $0}) .filter({($0 % 2) == 0}) .reduce(0,combine: {$0 + $1}) println(sumOfEvenSquaresInFirstTen) // => 220 ©"Farley"Caesar,"2015 80

Slide 81

Slide 81 text

Func%onal)Approach): Can$even$use$operators$as$the$argument$to$combine..$which$is$cool. let firstTenPositiveIntegers = [Int](1...10) let sumOfEvenSquaresInFirstTen = firstTenPositiveIntegers.map({$0 * $0}) .filter({($0 % 2) == 0}) .reduce(0,combine: +) println(sumOfEvenSquaresInFirstTen) // => 220 ©"Farley"Caesar,"2015 81

Slide 82

Slide 82 text

The$Swi($Sequence$Protocol Up#to#now,#we've#been#looking#at#calling#map,#filter,#reduce,#etc..#on# Array.#However,#Swi9#encodes#the#no=on#of#a#Sequence'Protocol.# map,#filter,#reduce,#and#other#transforma=on#func=ons#in#Swi9#are# also#global#func=ons#that#operate#on#any#item#that#implements#the# Sequence#Protocol.#In#addi=on#to#Array...#String,#Range,#and# Dic4onary#also#implement#the#Sequence'Protocol. ©"Farley"Caesar,"2015 82

Slide 83

Slide 83 text

Sequence'Protocol'-'Ranges'are'Sequences'Too map(1...3) {$0 * 2 } // => [2, 4, 6] ©"Farley"Caesar,"2015 83

Slide 84

Slide 84 text

Sequence'Protocol'-'Strings'are'just'sequences'of'Characters! func replaceAllOf(candidate: Character, with replacement: Character, inPassage passage: String) -> String { let replacedCharSequence = map(passage) { item -> Character in return (item == candidate ? replacement : item) } return String(replacedCharSequence) } replaceAllOf("o", with: "_", inPassage: "ooooooh this is pretty cool!") // => "______h this is pretty c__l!" ©"Farley"Caesar,"2015 84

Slide 85

Slide 85 text

Like%any%protocol%you%can%implement% the%Sequence'Protocol%on%your%own% types%too! ©"Farley"Caesar,"2015 85

Slide 86

Slide 86 text

I"❤️"this"pa)ern! • mechanism"(map,"filter,"reduce)"+" • pluggable"policy"(closure) ©"Farley"Caesar,"2015 86

Slide 87

Slide 87 text

I"❤️"this"pa)ern! Even%works%for%side.affecty%impera6ve%code. For$example$in$Ruby [1,2,3].each { |item| puts item } ; Outputs the following to the console: ; 1 ; 2 ; 3 ©"Farley"Caesar,"2015 87

Slide 88

Slide 88 text

Ruby [1,2,3].each_with_index { |item,index| puts("[#{index}]:#{item}") } ; Outputs the following to the console: ; [0]:1 ; [1]:2 ; [2]:3 ©"Farley"Caesar,"2015 88

Slide 89

Slide 89 text

I"❤️"this"pa)ern!"So"in"my"Swi3... extension Array { // Adds iteratng functions to array. // They take a closure that returns Void. // Specifically to be used for side effects func doForEach(closure: (T) -> Void) { for index in indices(self) { closure(self[index]) } } func doForEachWithIndex(closure: (T, Int) -> Void) { for index in indices(self) { closure(self[index], index) } } } ©"Farley"Caesar,"2015 89

Slide 90

Slide 90 text

Swi$ []1,2,3].doForEach { println($0) } // Outputs the following to the console: // 1 // 2 // 3 ©"Farley"Caesar,"2015 90

Slide 91

Slide 91 text

Swi$ [1,2,3].doForEachWithIndex { item, index in println("[\(index)]:\(item)") } // Outputs the following to the console: // [0]:1 // [1]:2 // [2]:3 ©"Farley"Caesar,"2015 91

Slide 92

Slide 92 text

Applica'on*Architecture How$does$func%onal$fit$in? ©"Farley"Caesar,"2015 92

Slide 93

Slide 93 text

Applica'on*Architecture • Cocoa&and&Cocoa&Touch&are&inherently&impera4ve • Don't&fight&the&framework ©"Farley"Caesar,"2015 93

Slide 94

Slide 94 text

So#how#do#we#infuse#func.onal#thinking#into#our#Cococa# applica.ons? • Func%onal)Core)/)Impera%ve)Shell"is"one"approach." • Proposed"as"an"applica1on"architecture"approach"(using"Ruby)"by" Gary"Bernhardt" h

Slide 95

Slide 95 text

Func%onal)Core)/)Impera%ve)Shell •"As"much"as"possible,"place"your" applica3on's"core"data"and"logic"in" immutable"constructs"(value"types). •"Push"state"out"to"the"'edges'."Represent" state"as"objects"with"mutable"references" to"immutable"core"constructs. ©"Farley"Caesar,"2015 95

Slide 96

Slide 96 text

Func%onal)Core)/)Impera%ve)Shell Benefits This%design%has%many%nice%side%effects.%For% example,%tes8ng%the%func8onal%pieces%is% very%easy,%and%it%o

Slide 97

Slide 97 text

Advanced(Func+onal(Tool(Box • Laziness • Flatmap • Currying • Functors,5Applica7ve5Functors • Monads ©"Farley"Caesar,"2015 97

Slide 98

Slide 98 text

Advanced(Func+onal(Tool(Box Will$not$be$touching$upon$these$concepts$ in$this$talk$(maybe&in&a&subsequent& presenta/on...&!).$ Some%good%resources: • Func%onal)Programming)in)Swi1" h$p:/ /www.objc.io/books/ • Why)is)a)Monad)Like)a)Wri%ng)Desk?" h$p:/ /www.infoq.com/presenta9ons/Why

Slide 99

Slide 99 text

UI#$#Can#We#Func-onalize#the#Impera-ve#Shell? "Right'now'we'write'UIs'by'poking'at'them,'manually'muta9ng'their' proper9es'when'something'changes,'adding'and'removing'views,' etc.'This'is'fragile'and'error@prone.'Some'tools'exist'to'lessen'the' pain,'but'they'can'only'go'so'far.'UIs'are'big,'messy,'mutable,' stateful'bags'of'sadness." —"Josh"Abernathy3" 3"h$p:/ /joshaber.github.io/2015/01/30/why:react:na=ve:ma$ers ©"Farley"Caesar,"2015 99

Slide 100

Slide 100 text

Func%onal)UI),)The)Holy)Grail So#can#we#have#a#purely#func1onal#UI?#That#is,#can#we#have#a# system#where#the#state#of#the#UI#is#an#immutable#value#that#is#then# rendered#for#display?#Where#new#values#of#the#UI#are#just#a# func1on#of#user#input#(which#is#also#modelled#as#immutable#values). Imagine(how(easy.... • Unit&tes)ng&the&UI • An&arbitrarily&large&number&of&levels&of&Undo ©"Farley"Caesar,"2015 100

Slide 101

Slide 101 text

Func%onal)UI),)The)Holy)Grail As#far#as#I#have#seen,#we're#not#quite#there.#But,#watch#this#space.# Some%research%in%this%area:% • Reac%ve'Cocoa" h$ps:/ /github.com/Reac5veCocoa/Reac5veCocoa • React'Na%ve" h$p:/ /www.reactna5ve.com/ • Func%onal'View'Controllers" h$p:/ /chris.eidhof.nl/posts/func5onal>view>controllers.html ©"Farley"Caesar,"2015 101

Slide 102

Slide 102 text

Where%do%we%go%from%here? We#just#skimmed#the#surface#of#func3onal#programming#in#Swi9.# This#is#a#fast#evolving#area#of#looking#at#how#to#employ#very#old# techniques#on#a#modern#pla?orm. ©"Farley"Caesar,"2015 102

Slide 103

Slide 103 text

Where%do%we%go%from%here? If#just#star*ng#out,#ease#your#way#into#this#topic.#Start#out#with#the# basics#and#slowly#level#up.#Be#wary#of#resources#that#quickly# devolve#into#overly#func*onal#jargon#and#advanced#concepts.#Swi?# is#not#purely#func*onal.#It#is#a#hybrid#of#OO#and#func*onal.#Some# are#trea*ng#it#as#Haskell.#It#is#not#that.#Func*onal#is#not#hard#but#it# is#deep.#Remember#the#Red#Pill#!...#The#rabbit#hole#of#func*onal# goes#down#preGy#far. Check&out:&Func%oning)as)a)Func%onalist&+&Andy&Matuschak h3p:/ /youtu.be/rJosPrqBqrA ©"Farley"Caesar,"2015 103

Slide 104

Slide 104 text

Where%to%go%from%here? • Check'out'the'resources'men/oned'in'earlier'slides'of'this'talk. • Check'out'the'presenta/ons'from'the'inaugural'Func/onal'Swi;' conference h

Slide 105

Slide 105 text

Par$ng'Words.... Moving'forward,'if'you'remember'nothing'else'from'this'talk,' remember'to: • Prefer&values&over&references • Prefer&pure&func0ons&over&impure&func0ons&and&procedures& • Reach&for&map,&reduce,&and&filter&over&for. ©"Farley"Caesar,"2015 105

Slide 106

Slide 106 text

The$Future$Is$ Func-onal ©"Farley"Caesar,"2015 106

Slide 107

Slide 107 text

Thank&You. Twi$er:(@publicfarley email:([email protected] #AlwaysBeCompiling ©"Farley"Caesar,"2015 107

Slide 108

Slide 108 text

Ques%ons,)Comments)? ©"Farley"Caesar,"2015 108

Slide 109

Slide 109 text

A"ribu'on • Clojure)logo)curtesy)of)clojure.com • Swi3)logo)curtesy)of)apple.com • Images)of)MacBook)and)Apple)Watch)are)curtesy)of)apple.com • Unless)otherwise)noted,)all)other)images)are)curtesy)of) pixabay.com ©"Farley"Caesar,"2015 109