×
Copy
Open
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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