Upgrade to Pro — share decks privately, control downloads, hide ads and more …

James Majors: What the Swiftly Func?

Realm
June 08, 2017

James Majors: What the Swiftly Func?

Realm

June 08, 2017
Tweet

More Decks by Realm

Other Decks in Technology

Transcript

  1. 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
  2. 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
  3. “A monad is a monoid in the category of endofunctors”

    http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html
  4. 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
  5. 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
  6. • Side-Effect Free • Stateless • Immutable (the Data anyway)

    Functional Programming (FP) An approach that Strives to be… http://bit.ly/AltConf2017
  7. 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’ */ } }
  8. OK Side Effect Mutate Data Change State When you think

    of… A Button on a Screen Object
  9. 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 }
  10. + 2 2 = 4 Side Effect Mutate Data Change

    State When you think of… Adding two numbers Function
  11. func squareANumber(x: Int) -> Int { return x * x

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

    } let squareANumber = { (x: Int) in x * x } Function: Closure Expression: Function Literal
  13. The value of ALL VARIABLES in an Object* at any

    instant in time http://bit.ly/AltConf2017
  14. class ShapeClass { var shape: Shape var lineColor: Color var

    fillColor: Color } 3 Choices 3 Choices 3 Choices 27 POSSIBLE STATES
  15. 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 { } }
  16. • Side-Effect Free • Stateless • Uses Immutable Data Functional

    Programming (FP) More or less(ish) http://bit.ly/AltConf2017
  17. 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
  18. 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’
  19. 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
  20. 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
  21. func doSomething(x: Int, function: ((Int) -> Int)) -> Int {

    Type: } return function(x) Type: Type: Closure
  22. } 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)
  23. } 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)
  24. } 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)
  25. } 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)
  26. 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
  27. 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
  28. 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
  29. 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 }
  30. Function take a Function as an argument Function return a

    Function Closure Closure http://bit.ly/AltConf2017
  31. Higher-Order Functions Function that takes a Function as an argument

    Function that returns a Function Function that takes and returns a Function
  32. 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)
  33. 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
  34. Map func map<T, U>( function: (T) -> U) -> [U]

    let new = [1,2,3,4,5].map { 10 * $0 }
  35. Function [Array] [Results] { 10 * number } { 10

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

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

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

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

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

    -> [U] Int, Float, String, class, struct… Generic Types
  41. T = Some Type U = Some Type func map<T,

    U>(function: (T) -> U) -> [U] Int, Float, String, class, struct… Int, Float, String, class, struct… Generic Types
  42. 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 [ , ]
  43. 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
  44. 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
  45. 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 [ , ]
  46. 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
  47. 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
  48. Filter let new = [1,2,3,4,5].filter { $0 % 2 ==

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

    0 } // new = [2,4] func filter<T>(function: (T) -> Bool) -> [T]
  50. { $0 + $1 } Reduce func reduce<T>( initialValue: T,

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

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

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

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

    -> T let new = [1,2,3,4,5].reduce(0, + )
  55. Result [ , , , , ] 1 2 3

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

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

    4 5 Function [Array] + } { x acc = 0 0
  58. { $0 + $1 } Reduce func reduce<T>( initialValue: T,

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

    -> T let new = [1,2,3,4,5].reduce(0, + ) // new = 15
  60. 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
  61. 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
  62. let mapped = array.map { $0 * 10 } let

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

    filtered = array.filter { $0 % 2 == 0 } let array = [1,2,3,4,5]
  64. 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]
  65. 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]
  66. 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 }
  67. 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 }
  68. func addClosure(x: Int) -> ((Int) -> Int) { return {

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

    y in x * y } } let add = addClosure(x: 10) add(100) // 1000 add(10) // 100 x x
  70. ((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
  71. 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