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

Ready for the future

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Ready for the future

Swift is brand spanking new. How can we possibly be expected to write idiomatic code? On the other hand, Objective-C has been around for more than thirty years. We know what it looks like and feels like. The Objective-C of our iOS youth is very different than today’s Objective-C. Seen in this light, Swift is more evolutionary than you might think. In this talk we’ll look at Swift code in the light of the code of Objective-C and other languages that have come before it.

Daniel Steinberg http://dimsumthinking.com

Avatar for do{iOS} conference

do{iOS} conference

November 09, 2015
Tweet

More Decks by do{iOS} conference

Other Decks in Programming

Transcript

  1. Lasagne » Bolognese sauce » Lasagne sheets » Béchamel sauce

    » Grated parmesan Béchamel is one of the mother sauces
  2. Lasagne » Bolognese sauce » Lasagne sheets » Béchamel sauce

    » Grated parmesan Bechamel Sauce » Butter » Flour » Milk » Salt and Pepper
  3. Lasagne » Bolognese sauce » Lasagne sheets » Béchamel sauce

    » Grated parmesan Bechamel Sauce » Butter » Flour » Milk » Salt and Pepper
  4. Lasagne » Bolognese sauce » Lasagne sheets » Béchamel sauce

    » Grated parmesan Bechamel Sauce » Butter » Flour » Milk » Salt and Pepper Context matters
  5. - (NSTimeInterval)elapsed Time { NSDate *now = [[NSDate alloc] init];

    NSTimeInterval elapsed Time = [now timeIntervalS inceDate:self.startTime]; return elapsedTime; }
  6. - (NSTimeInterval)elapsed Time { NSDate *now = [[NSDate alloc] init];

    NSTimeInterval elapsed Time = [now timeIntervalS inceDate:self.startTime]; return elapsedTime; }
  7. - (NSTimeInterval)elapsed Time { NSDate *now = [[NSDate alloc] init];

    NSTimeInterval elapsed Time = [now timeIntervalS inceDate:self.startTime]; return elapsedTime; }
  8. - (NSTimeInterval)elapsed Time { NSDate *now = [[NSDate alloc] init];

    NSTimeInterval elapsed Time = [now timeIntervalS inceDate:self.startTime]; return elapsedTime; }
  9. - (NSTimeInterval)elapsed Time { NSDate *now = [[NSDate alloc] init];

    NSTimeInterval elapsed Time = [now timeIntervalS inceDate:self.startTime]; return elapsedTime; }
  10. Lasagne » Bolognese sauce » Lasagne sheets » Béchamel sauce

    » Grated parmesan Bechamel Sauce » Butter » Flour » Milk » Salt and Pepper
  11. import GameplayKit struct AppSales: SequenceType { let numberOfDays: Int let

    randomDistribution = GKGaussianDistribution(lowestValue: 0, highestValue: 10) func generate() -> Any Generator<Int> { var count = 0 return anyGenerator({ if count++ < self .numberOfDays { return self .randomDistribution.nextInt() } else { return nil } }) } }
  12. import GameplayKit struct AppSales: SequenceType { let numberOfDays: Int let

    randomDistribution = GKGaussianDistribution(lowestValue: 0, highestValue: 10) func generate() -> Any Generator<Int> { var count = 0 return anyGenerator({ if count++ < self .numberOfDays { return self .randomDistribution.nextInt() } else { return nil } }) } }
  13. import GameplayKit struct AppSales: SequenceType { let numberOfDays: Int let

    randomDistribution = GKGaussianDistribution(lowestValue: 0, highestValue: 10) func generate() -> Any Generator<Int> { var count = 0 return anyGenerator({ if count++ < self .numberOfDays { return self .randomDistribution.nextInt() } else { return nil } }) } }
  14. import GameplayKit struct AppSales: SequenceType { let numberOfDays: Int let

    randomDistribution = GKGaussianDistribution(lowestValue: 0, highestValue: 10) func generate() -> Any Generator<Int> { var count = 0 return anyGenerator({ if count++ < self .numberOfDays { return self .randomDistribution.nextInt() } else { return nil } }) } }
  15. import GameplayKit struct AppSales: SequenceType { let numberOfDays: Int let

    randomDistribution = GKGaussianDistribution(lowestValue: 0, highestValue: 10) func generate() -> Any Generator<Int> { var count = 0 return anyGenerator({ if count++ < self .numberOfDays { return self .randomDistribution.nextInt() } else { return nil } }) } }
  16. import GameplayKit struct AppSales: SequenceType { let numberOfDays: Int let

    randomDistribution = GKGaussianDistribution(lowestValue: 0, highestValue: 10) func generate() -> Any Generator<Int> { var count = 0 return anyGenerator({ if count++ < self .numberOfDays { return self .randomDistribution.nextInt() } else { return nil } }) } }
  17. import GameplayKit struct AppSales: SequenceType { let numberOfDays: Int let

    randomDistribution = GKGaussianDistribution(lowestValue: 0, highestValue: 10) func generate() -> Any Generator<Int> { var count = 0 return anyGenerator({ if count++ < self .numberOfDays { return self .randomDistribution.nextInt() } else { return nil } }) } }
  18. 6 5 6 4 6 4 3 let lastWeeksSales =

    AppSales(numberOfDays: 7) for dailySales in lastWeeksSales { print(dailySales) }
  19. [6.964999999999999, 8.357999999999999, 5.572, 6.964999999999999, 5.572, 4.178999999999999, 4.178999999999999] let lastWeeksSales =

    AppSales(numberOfDays: 7) let lastWeeksRevenues = lastWeeksSales.map{dailySales in Double(dailySales) * 1.99 * 0.70 }
  20. let lastWeeksSales = AppSales(numberOfDays: 7) let unitPrice = 1.99 let

    lastWeeksRevenues = lastWeeksSales.map{dailySales in Double(dailySales) * unitPrice * 0.70 }
  21. let lastWeeksSales = AppSales(numberOfDays: 7) let unitPrice = 1.99 let

    lastWeeksRevenues = lastWeeksSales.map{dailySales in Double(dailySales) * unitPrice * 0.70 }
  22. let lastWeeksSales = AppSales(numberOfDays: 7) let unitPrice = 1.99 let

    sellersPercentage = 0.70 let lastWeeksRevenues = lastWeeksSales.map{dailySales in Double(dailySales) * unitPrice * sellersPercentage }
  23. let lastWeeksSales = AppSales(numberOfDays: 7) let unitPrice = 1.99 let

    sellersPercentage = 0.70 let lastWeeksRevenues = lastWeeksSales.map{dailySales in Double(dailySales) * unitPrice * sellersPercentage }
  24. let lastWeeksSales = AppSales(numberOfDays: 7) let unitPrice = 1.99 let

    sellersPercentage = 0.70 func revenuesForCopies Sold(numberOfCopies: Int) -> Double { return Double(number OfCopies) * unitPrice * sellersPercentage } let lastWeeksRevenues = lastWeeksSales.map{dailySales in revenuesForCopiesSold(dailySales) }
  25. func negativeNumbersToZero (number: Int) -> Int { return max(0, number)

    } let lastWeeksRevenues = lastWeeksSales.map(negativeNumbersToZero) .map(revenuesForCopiesSold)
  26. typealias USDollars = Double func revenues ForCopiesSold(numberOfCopies: Int) -> USDollars

    { return Double(numberOfCopies) * unitPrice * sellersPercentage }
  27. typealias USDollars = Double func revenues ForCopiesSold(numberOfCopies: Int) -> USDollars

    { return Double(numberOfCopies) * unitPrice * sellersPercentage } func toThe NearestPenny(dollarAmount: USDollars) -> USDollars { return round(dollarAmount * 100)/100 }
  28. typealias USDollars = Double func revenues ForCopiesSold(numberOfCopies: Int) -> USDollars

    { return Double(numberOfCopies) * unitPrice * sellersPercentage } func toThe NearestPenny(dollarAmount: USDollars) -> USDollars { return round(dollarAmount * 100)/100 } func revenues InDollarsForCopiesSold(numberOfCopies: Int) -> USDollars { return toTheNearestPenny(revenuesForCopiesSold (numberOfCopies)) }
  29. typealias USDollars = Double func revenues ForCopiesSold(numberOfCopies: Int) -> USDollars

    { return Double(numberOfCopies) * unitPrice * sellersPercentage } func toThe NearestPenny(dollarAmount: USDollars) -> USDollars { return round(dollarAmount * 100)/100 } func revenues InDollarsForCopiesSold(numberOfCopies: Int) -> USDollars { return toTheNearestPenny(revenuesForCopiesSold (numberOfCopies)) }
  30. typealias USDollars = Double func revenues ForCopiesSold(numberOfCopies: Int) -> USDollars

    { return Double(numberOfCopies) * unitPrice * sellersPercentage } func toThe NearestPenny(dollarAmount: USDollars) -> USDollars { return round(dollarAmount * 100)/100 } func revenues InDollarsForCopiesSold(numberOfCopies: Int) -> USDollars { return toTheNearestPenny(revenuesForCopiesSold (numberOfCopies)) }
  31. typealias USDollars = Double func revenues ForCopiesSold(numberOfCopies: Int) -> USDollars

    { return Double(numberOfCopies) * unitPrice * sellersPercentage } func toThe NearestPenny(dollarAmount: USDollars) -> USDollars { return round(dollarAmount * 100)/100 } func revenues InDollarsForCopiesSold(numberOfCopies: Int) -> USDollars { return toTheNearestPenny(revenuesForCopiesSold (numberOfCopies)) }
  32. func replaceNegativeSalesWithZeroSales(sales: [Int]) -> [Int] { return sales.map(negativeNumbersToZero) } func

    calculateRevenuesFromSales(sales: [Int]) -> [USDollars] { return sales.map(revenuesInDollarsFor CopiesSold) }
  33. func replaceNegativeSalesWithZeroSales(sales: [Int]) -> [Int] { return sales.map(negativeNumbersToZero) } func

    calculateRevenuesFromSales(sales: [Int]) -> [USDollars] { return sales.map(revenuesInDollarsFor CopiesSold) }
  34. let lastWeeksSales = AppSales(numberOfDays: 7) func replaceNegativeSalesWithZeroSales(sales: [Int]) -> [Int]

    { return sales.map(negativeNumbersToZero) } func calculateRevenuesFromSales(sales: [Int]) -> [USDollars] { return sales.map(revenuesInDollarsFor CopiesSold) }
  35. Lasagne » Bolognese sauce » Lasagne sheets » Béchamel sauce

    ̣ Butter ̣ Flour ̣ Milk ̣ Salt and Pepper » Grated parmesan
  36. let lastWeeksRevenues = lastWeeksSales .map{$0 > 0 ? $0 :

    0} .map{round(Double($0) * unitPrice * sellersPercentage * 100)/100 }
  37. Lasagne » Bolognese sauce » Lasagne sheets » Béchamel sauce

    » Grated parmesan Bechamel Sauce » Butter » Flour » Milk » Salt and Pepper
  38. uesInDollarsForCopiesSold(numberOfCopies: Int) -> USDollars { numberOfCopies » revenuesForCopiesSold » roundedToTheNearestPenny

    func revenuesForCopiesSold(numberOfCopies: NumberOfCopies) -> USDollars { return Double(numberOfCopies) * unitPrice * sellersPercentage }
  39. »

  40. typealias NumberOfCopies = Int func revenues ForCopiesSold(numberOfCopies: Number OfCopies) ->

    USDollars { return Double(numberOfCopies) * unitPrice * sellersPercentage }
  41. extension NumberOfCopies { private func revenuesIn DollarsForCopiesSold() -> USDollars {

    return self.revenues ForCopiesSold().roundedToTheNearestPenny () } }
  42. extension NumberOfCopies { private func revenuesIn DollarsForCopiesSold() -> USDollars {

    return self.revenues ForCopiesSold().roundedToTheNearestPenny () } }
  43. extension NumberOfCopies { private func revenuesIn DollarsForCopiesSold() -> USDollars {

    return self.revenues ForCopiesSold().roundedToTheNearestPenny () } }
  44. extension NumberOfCopies { private func revenuesIn DollarsForCopiesSold() -> USDollars {

    return self.revenues ForCopiesSold().roundedToTheNearestPenny () } }
  45. extension NumberOfCopies { private func revenuesIn DollarsForCopiesSold() -> USDollars {

    return self.revenues ForCopiesSold().roundedToTheNearestPenny () } }
  46. extension NumberOfCopies { private func revenuesIn DollarsForCopiesSold() -> USDollars {

    return self.revenues ForCopiesSold().roundedToTheNearestPenny () } }
  47. extension NumberOfCopies { private func revenuesIn DollarsForCopiesSold() -> USDollars {

    return self.revenues ForCopiesSold().roundedToTheNearestPenny () } }
  48. extension NumberOfCopies { private func revenues InDollarsForCopiesSold() -> USDollars {

    return revenues ForCopiesSold().roundedToTheNearestPenny () } }
  49. func anArrayOf DailySales(rawSales: AppSales) -> [Int] { return rawSales.map{$0} }

    func replace NegativeSalesWithZeroSales(sales: [Int]) -> [Int] { return sales.map(negativeNumbersToZero) } func calcu lateRevenuesFromSales(sales: [Int]) -> [USDollars] { return sales.map(revenuesInDollarsForCopiesSold) }
  50. func anArrayOf DailySales(rawSales: AppSales) -> [Int] { return rawSales.map{$0} }

    func replace NegativeSalesWithZeroSales(sales: [Int]) -> [Int] { return sales.map(negativeNumbersToZero) } func calcu lateRevenuesFromSales(sales: [Int]) -> [USDollars] { return sales.map(revenuesInDollarsForCopiesSold) } func processEndToEnd(sales: AppSales) -> USDollars { return sales.map(transform: Int -> U) }
  51. func combinedSteps(input: Int) -> USDollars { return input » negativeNumbersToZero

    » revenuesInDollarsForCopiesSold } func processEndToEnd(sales: AppSales) -> [USDollars] { return sales.map(combinedSteps) }
  52. func combinedSteps(input: Int) -> USDollars { return input » negativeNumbersToZero

    » revenuesInDollarsForCopiesSold } func processEndToEnd(sales: AppSales) -> [USDollars] { return sales.map(combinedSteps) }
  53. func combinedSteps(input: Int) -> USDollars { return input » negativeNumbersToZero

    » revenuesInDollarsForCopiesSold } func processEndToEnd(sales: AppSales) -> [USDollars] { return sales.map(combinedSteps) }
  54. func combinedSteps(input: Int) -> USDollars { return input » negativeNumbersToZero

    » revenuesInDollarsForCopiesSold } func processEndToEnd(sales: AppSales) -> [USDollars] { return sales.map(combinedSteps) }
  55. func »<T,U,V> (firstFunction: T -> U, secondFunction: U -> V)

    -> T -> V { return {x in secondFunction(firstFunction(x)) } }
  56. func »<T,U,V> (firstFunction: T -> U, secondFunction: U -> V)

    -> T -> V { return {x in secondFunction(firstFunction(x)) } }
  57. func »<T,U,V> (firstFunction: T -> U, secondFunction: U -> V)

    -> T -> V { return {x in secondFunction(firstFunction(x)) } }
  58. func »<T,U,V> (firstFunction: T -> U, secondFunction: U -> V)

    -> T -> V { return {x in secondFunction(firstFunction(x)) } }
  59. func »<T,U,V> (firstFunction: T -> U, secondFunction: U -> V)

    -> T -> V { return {x in secondFunction(firstFunction(x)) } }
  60. map

  61. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  62. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  63. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  64. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  65. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  66. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  67. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  68. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  69. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  70. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  71. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  72. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  73. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  74. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  75. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  76. extension SequenceType { func mapUsingReduce <U>(transform: Generator.Element -> U) ->

    [U] { let initialValue = [U]() func step(accu mulatedValue: [U], nextElement: Generator .Element) -> [U] { return acc umulatedValue + [transform(nextElement)] } return reduce (initialValue, combine: step) } }
  77. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  78. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  79. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  80. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  81. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  82. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  83. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  84. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  85. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  86. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  87. func filterUsingReduce (includeElement: Generator.Element -> Bool) -> [Generator.Element] { let

    initialValue = Array<Generator.Element>() func step(accumula tedValue: [Generator.Element], next Element: Generator.Element) -> [Generator .Element] { guard include Element(nextElement) else { return acc umulatedValue } return accumula tedValue + [nextElement] } return reduce(ini tialValue, combine: step) }
  88. func anArrayOfDailySales(rawSales: AppSales) -> [Int] { return rawSales.map{$0} } func

    replaceNegativeSalesWithZero Sales(sales: [Int]) -> [Int] { return sales.map(negative NumbersToZero) } func calculateRevenuesFromSales(sales: [Int]) -> [USDollars] { return sales.map(revenuesInDollars ForCopiesSold) }
  89. func anArrayOfDailySales(rawSales: AppSales) -> [Int] { return rawSales.mapUsingReduce{$0} } func

    replaceNegativeSalesWithZero Sales(sales: [Int]) -> [Int] { return sales.mapUsingReduce(negative NumbersToZero) } func calculateRevenuesFromSales(sales: [Int]) -> [USDollars] { return sales.mapUsingReduce(revenues InDollarsForCopiesSold) }
  90. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  91. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  92. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  93. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  94. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  95. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  96. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  97. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  98. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  99. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  100. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  101. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  102. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  103. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  104. transducer U, (U, T) -> U U, (U, S) ->

    U f: S -> T [T] -> U [S] -> U
  105. transducer [USDollars], ([USDollars], T) -> [USDollars] [USDollars], ([USDollars], S) ->

    [USDollars] f: S -> T [T] -> [USDollars] [S] -> [USDollars]
  106. transducer [USDollars], ([USDollars], T) -> [USDollars] [USDollars], ([USDollars], S) ->

    [USDollars] f: S -> T [T] -> [USDollars] [S] -> [USDollars]
  107. transducer [USDollars], ([USDollars], NumberOfCopies) -> USDollars [USDollars], ([USDollars], S) ->

    [USDollars] f: S -> NumberOfCopies [NumberOfCopies] -> [USDollars] [S] -> [USDollars]
  108. transducer [USDollars], ([USDollars], NumberOfCopies) -> USDollars [USDollars], ([USDollars], S) ->

    [USDollars] f: S -> NumberOfCopies [NumberOfCopies] -> [USDollars] [S] -> [USDollars] reduce with revenueInDollarsForCopiesSold
  109. transducer [USDollars], ([USDollars], NumberOfCopies) -> USDollars [USDollars], ([USDollars], S) ->

    [USDollars] f: S -> NumberOfCopies [NumberOfCopies] -> [USDollars] [S] -> [USDollars]
  110. transducer [USDollars], ([USDollars], NumberOfCopies) -> USDollars [USDollars], ([USDollars], S) ->

    [USDollars] negativeNumbersToZero: NumberOfCopies -> NumberOfCopies [NumberOfCopies] -> [USDollars] [S] -> [USDollars]
  111. transducer [USDollars], ([USDollars], NumberOfCopies) -> USDollars [USDollars], ([USDollars], S) ->

    [USDollars] negativeNumbersToZero: Int -> NumberOfCopies [NumberOfCopies] -> [USDollars] [S] -> [USDollars]
  112. transducer [USDollars], ([USDollars], NumberOfCopies) -> USDollars [USDollars], ([USDollars], Int) ->

    [USDollars] negativeNumbersToZero: Int -> NumberOfCopies [NumberOfCopies] -> [USDollars] [Int] -> [USDollars]
  113. transducer [USDollars], ([USDollars], NumberOfCopies) -> USDollars [USDollars], ([USDollars], Int) ->

    [USDollars] negativeNumbersToZero: Int -> NumberOfCopies [NumberOfCopies] -> [USDollars] [Int] -> [USDollars] reduce implementation of the composition