Skip to content

Instantly share code, notes, and snippets.

@donnywals
Created November 9, 2015 16:48
Show Gist options
  • Save donnywals/c4f458517ef45539b8c9 to your computer and use it in GitHub Desktop.
Save donnywals/c4f458517ef45539b8c9 to your computer and use it in GitHub Desktop.

Daniel Sternberg - Ready for the future

  • Objective-C is not dead, it’s awesome, it’s a lovely language but you just won’t find a job if stick to it.
  • Daniel misses the Objective-C’s * in Swift. Because that way he knows that something is (or isn’t) a reference type. He also misses header files because those are nice overviews of what he can call in a certain class. Otherwise, he loves Swift.
  • Context is important in code. If you would want to get timeIntervalUntilNow you need the inverse of timeIntervalSinceNow because the latter would return a negative number. Just putting a - in front of it somewhere is bad, because there’s no context. Wrapping it in a method, - is okay to put there. That provides context. So timeIntervalUntilNow would just return -timeIntervalSinceNow.
  • Translating things from Objective-C to Swift is not thinking in Swift. Thinking in Swift doesn’t mean monads, map, flatmap, reduce and all the haskell stuff.
  • If you use protocols, like SequenceType you get a lot for free on certain models. If you would have a model with your app sales and you make your AppSales struct conform to SequenceType you could easily iterate through your numbers, you could use a map function to calculate revenue and more.
  • A revenue calculation could be Double(dailySales) * 0.99 * 0.70 but that looks pretty abstract. Cleaner code would be: Double(dailySales) * unitPrice * sellersPercentage. And pulling that out from a map function and putting the calc into a function you could write something like: appSales.map(appRevenueForCopies). Filtering out anything < 0 like this appSales.map{$0 > 0 ? $0 : 0}.map(appRevenueForCopies). But that’s not very readable. Better code: appSales.map(negativeToZero).map(appRevenueForCopies).
  • The appRevenueForCopies function returns a Double. But it’s not obvious what that double is. You create typealias USDollars = Double. Rounding the revenue in a function could result in something like: toTheNearestPenny(appRevenueForCopies(copiesSold)). But that’s backwards, you read it inside out.
  • Doing infix >> {associativity left} helps. Function body is like this.
func >> <T, U>(input:T, transform: T->U) -> U { 
    return transform(input)
}

toTheNearestPenny(appRevenueForCopies(copiesSold)) can now be written as numberOfCopies >> revenueForCopies >> toTheNearestPenny.

  • appSales.map{$0 > 0 ? $0 : 0}.map(appRevenueForCopies) isn’t very pretty. Pulling that apart to two functions is better. func replaceNegativeWithZero(), func arrayOfSales() and func calcRevenueFromSales(). With the new infix: appSales >> arrayOfSales >> replaceNegativeWithZero >> calcRevenueFromSales. This is very readable. Maybe not super transparent but you abstract away all the cruft. If you want to know more you can zoom in on each component of this.
  • But.. custom operators. Can we do it without? Yes. If we extend Int we can put a private method on an Int extension that returns a double. We can do the same with rounding to the nearest penny on Double. And then extending Int again we can return revenueForCopiesSold().roundedToTheNearestPenny(). Resulting in code like 7.revenueForCopiesSold().
  • Reduce is map, flatmap and filter. All at once. Try to implement map, flatmap and filter using a reduce call and generics. It’s not efficient or a good idea per se but it looks very interesting. Performance for this implementation is not good.
  • Transducers can help with this. There’s no formal implementation in Swift but there’s examples if you look for them. A transducer takes a function from S to T (f: S -> T). [Copies]->[USDollars] = T. [Int]->[USDollars] = S so f: S -> T is actually f: Int -> USDollars. I really didn’t understand this last part.. it was so complex and amazing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment