200

My talk from AltConf 2015

June 10, 2015

## Transcript

1. 1.

@abizern | abizern.org Swift Contractor - Shutl
2. 2.

3. 3.

4. 4.

5. 5.

6. 6.

### summer :: Int -> Int -> Int summer a b

= a + b λ> :t summer summer :: Int -> Int -> Int
7. 7.

### --summer :: Int -> Int -> Int summer a b

= a + b λ> :t summer summer :: Num a => a -> a -> a
8. 8.

### λ> :i + class Num a where (+) :: a

-> a -> a ... -- Defined in ‘GHC.Num’ infixl 6 +
9. 9.

10. 10.

### ▸ Values don’t change under you. ▸ Easier to maintain

the code. ▸ More likely to be thread safe.
11. 11.

### ▸ Prefer let to var ▸ Prefer structs over classes

where possible. ▸ Avoid mutating structs.
12. 12.

13. 13.
14. 14.

15. 15.

16. 16.

### HIGHER ORDER FUNCTIONS let list = [1, 2, 3, 4]

let squares = list.map{\$0 * \$0} let evens = list.filter{\$0 % 2 == 0} let sum = list.reduce(0, combine: +)
17. 17.

### REDUCE IS OFTEN ENOUGH let squares2 = list.reduce([Int]()) { var

accum = \$0 accum.append(\$1 * \$1) return accum } let evens2 = list.reduce([Int]()){ if \$1 % 2 == 0 { var accum = \$0 accum.append(\$1) return accum } else { return \$0 } }
18. 18.

### MAPPING AND FILTERING IS MORE EXPRESSIVE let sumOfSquaresOfEvenNumbers = list

.filter{ \$0 % 2 == 0 } .map { \$0 * \$0 } .reduce(0, combine: +)
19. 19.

20. 20.

### A monad is a monoid in the category of endofunctors,

what’s the problem? -- Philip Wadler1 1 Not really – see http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html
21. 21.

22. 22.

23. 23.

### ▸ Optional is a context that contains a value or

the lack of a value
24. 24.

an order
25. 25.

### ▸ Result is the context that has a value or

an error in getting that value
26. 26.

27. 27.

28. 28.

solution"
29. 29.

### typealias is useful for making code clearer. func decode(json: [String

: AnyObject]) -> MyType { ... } or typealias JSONDictionary = [String : AnyObject] func decode(json: JSONDictionary) -> myType { ... }
30. 30.

### It can make higher order function declarations easier to read.

// Taken from AlamoFire typealias JSONResponseHandler = (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> () // Define a common completion block with specific handler func responseHandlerWithCompletion(completion: Result<MyType>) -> JSONResponseHandler { ... }
31. 31.

the types and transformations of those types, before writing any code.
32. 32.

33. 33.

### func shuffle(deck: Deck) -> Deck { ... } func deal(deck:

Deck, toPlayers: [Player]) -> [Hand] { ... } func winner(hands: [Hand]) -> Player { ... }
34. 34.

35. 35.

### module Main where import Control.Monad import Numeric factoryTimes :: Double

-> Double -> [Double] factoryTimes c f = 0.0 : [ c / (2.0 + k * f) | k <- [0.0, 1.0 ..]] productionTimes :: Double -> Double -> [Double] productionTimes x f = [ x / (2.0 + k * f) | k <- [0.0, 1.0 ..]] times :: Double -> Double -> Double -> [Double] times c f x = zipWith (+) production factory where production = productionTimes x f factory = scanl1 (+) \$ factoryTimes c f firstMinimum :: [Double] -> Double firstMinimum (x:y:ys) = if x < y then x else firstMinimum (y:ys) solve :: Double -> Double -> Double -> Double solve c f x = firstMinimum \$ times c f x main :: IO () main = do t <- getLine forM_ [1..read t :: Int] \$ \i -> do [c, f, x] <- fmap (map read . words) getLine let result = solve c f x putStrLn \$ concat ["Case #", show i, ": ", Numeric.showFFloat (Just 7) result ""]
36. 36.

37. 37.

### ▸ Don't have state, have functions that return values; although

this is easier said than done. ▸ Higher order functions can be used to reduce duplication in code.
38. 38.

### ▸ Aim to write small, pure functions with no side

effects. ▸ Avoid mixing pure and impure code. ▸ Aim to write small, obviously correct functions.
39. 39.

### Composition infix operator >>> { associativity right precedence 170 }

func >>> <A, B, C>(f: B -> C, g: A -> B) -> A -> C { return { x in f(g(x)) } }
40. 40.

### Map on Optionals infix operator <^> { associativity left }

func <^> <A, B>(f: A -> B, a: A?) -> B? { if let x = a { return f(x) } else { return nil } }
41. 41.

### Applicative on Optionals infix operator <*> { associativity left }

func <*> <A, B>(lhs: (A -> B)?, rhs: A?) -> B? { if let f = lhs { if let x = rhs { return f(x) } } return nil }
42. 42.

### Bind on Optionals infix operator >>== { associativity left precedence

150 } func >>== <A, B>(a:A?, f: A -> B?) -> B? { if let x = a { return f(x) } else { return nil } }
43. 43.

44. 44.

### OOP concerns data objects and operations on those data objects

— My naive definition
45. 45.

### "Why are methods of protocols defined outside the Type?" struct

SomeType: Equatable { ... } func ==(lhs: ...
46. 46.

### If we are supposed to favour immutability, shouldn't we be

moving away from classes?
47. 47.

### Have you ever created a class with nothing but class

functions just to keep related code together?
48. 48.

### Have you ever carefully exposed only the methods that were

safe to call on your objects, keeping other methods private?
49. 49.

### If you have pure functions (no side effects, same inputs,

same outputs) is it worth worrying about their access modifiers? Can you make them bare functions instead?
50. 50.

### If the functions can be grouped together into a logical

set of functionality, could a protocol be defined to encompass that functionality instead?
51. 51.

### Programming to an interface was a recommendation even in the

times of Objective-C. The stronger type system in Swift makes it even more attractive.
52. 52.

53. 53.

54. 54.

55. 55.

56. 56.

57. 57.

58. 58.

59. 59.

### WITH COCOA WE HAVE THE CHOICE OF TWO DIFFERENT APPROACHES

TO THE SAME PROBLEM SPACE.
60. 60.

61. 61.

### I want to write code like this: static func decode(object:

JSON) -> DateWithTimeZone? { return jsonDictionary(object) >>== { dict in DateWithTimeZone.create <^> dict[dateWithTimeFormatKey(.Date)] >>== jsonDate <*> dict[dateWithTimeFormatKey(.TimeZone)] >>== jsonTimeZone } } It looks complex because it's unfamiliar, but it's clearer than having a pyramid of doom.
62. 62.

### This stuff is hard. But compared with what we already

do and what we aspire to do; it's perfectly within our grasp.
63. 63.

### THANK YOU & HAVE A GREAT WEEK! ABIZER NASIR |

@ABIZERN | ABIZERN.ORG