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

Adopting Functional Programming

Adopting Functional Programming

Apple’s new language Swift supports functional programming while being tightly integrated with Objective-C and Cocoa. This has sent the developer community on an adventure to explore how ideas from functional programming might help writing great apps for iOS and OS X. In this talk, I will concentrate on two of these ideas: types and immutable data structures. How do they benefit development, and how do they affect code architecture?

This talk was presented at Sydney CocoaHeads who have kindly produced a video of the talk: http://sydneycocoaheads.com/2014/08/27/swift-adopting-functional-programming-by-manuel-chakravarty/

Manuel Chakravarty
PRO

August 21, 2014
Tweet

More Decks by Manuel Chakravarty

Other Decks in Programming

Transcript

  1. Manuel M T Chakravarty
    University of New South Wales
    Adopting Functional Programming
    mchakravarty
    TacticalGrace
    justtesting.org
    1
    45 minute time slot
    [15+min Intro & What is FP?; 15-min Love Types; 15-min Minimise State]

    View Slide

  2. 2
    My FP background:
    * Co-founder of the Programming Languages & Systems research group at UNSW
    * Internationally renowned research group: Haskell standardisation & type system; parallel
    programming
    * Program Chair of ICFP 2014

    View Slide

  3. GPUs
    multicore
    CPUs
    3
    * Current work focuses on array programming for high-performance architectures, such as
    GPUs and multicores.

    View Slide

  4. BIGPIXEL
    4
    My Cocoa background:
    * BigPixel — pixel art and sprite editor for iPad
    * New mixed-language Mac app
    » Let’s talk about Swift…

    View Slide

  5. BIGPIXEL
    4
    My Cocoa background:
    * BigPixel — pixel art and sprite editor for iPad
    * New mixed-language Mac app
    » Let’s talk about Swift…

    View Slide

  6. Swift
    Objective-C without the C
    5
    * Craig Federighi (apparently): Objective-C without the C
    * But Chris Lattner corrected that on the DevForums: ObjC + FP devforums.apple.com/message/1025388#1025388>

    View Slide

  7. Swift
    Objective-C with functional programming
    5
    * Craig Federighi (apparently): Objective-C without the C
    * But Chris Lattner corrected that on the DevForums: ObjC + FP devforums.apple.com/message/1025388#1025388>

    View Slide

  8. “What is
    functional programming?”
    6
    » What is functional programming?
    [Audience opinions…]

    View Slide

  9. Types systems
    Types inference
    Generics
    Pattern matching
    REPL
    Higher-order
    functions
    Immutable
    structures
    Garbage collection
    Closures
    Purity
    Well-defined
    semantics
    Meta programming
    Equational
    reasoning
    List comprehensions
    Lambda calculus
    Monads etc.
    7
    * Collection of technologies
    * Usually draw inspiration from mathematics
    * Aimed at improving program composition
    * Modern Objective-C already adopts some of these technologies
    * Swift adopts many more

    View Slide

  10. Types systems
    Types inference
    Generics
    Pattern matching
    REPL
    Higher-order
    functions
    Closures
    Garbage collection
    Immutable
    structures Purity
    Well-defined
    semantics
    Meta programming
    Equational
    reasoning
    List comprehensions
    Lambda calculus
    Monads etc.
    7
    * Collection of technologies
    * Usually draw inspiration from mathematics
    * Aimed at improving program composition
    * Modern Objective-C already adopts some of these technologies
    * Swift adopts many more

    View Slide

  11. Types inference
    Types systems
    Higher-order
    functions
    Generics
    REPL
    Pattern matching
    Closures
    Garbage collection
    Immutable
    structures Purity
    Well-defined
    semantics
    Meta programming
    Equational
    reasoning
    List comprehensions
    Lambda calculus
    Monads etc.
    7
    * Collection of technologies
    * Usually draw inspiration from mathematics
    * Aimed at improving program composition
    * Modern Objective-C already adopts some of these technologies
    * Swift adopts many more

    View Slide

  12. ?
    8
    * It’s great to have a new language with lots of new, exciting features, but…
    * …it also leads to many questions.
    * When should you start looking into it? How to use new features?
    * What is the right way to use it? Where to use it? Where to find the time?
    * Consider this: How much Swift in WWDC 2014 videos? What about 2015?

    View Slide

  13. ?
    When?
    How?
    What?
    Where?
    8
    * It’s great to have a new language with lots of new, exciting features, but…
    * …it also leads to many questions.
    * When should you start looking into it? How to use new features?
    * What is the right way to use it? Where to use it? Where to find the time?
    * Consider this: How much Swift in WWDC 2014 videos? What about 2015?

    View Slide

  14. ?
    When?
    How?
    What?
    Where?
    WWDC
    2015
    8
    * It’s great to have a new language with lots of new, exciting features, but…
    * …it also leads to many questions.
    * When should you start looking into it? How to use new features?
    * What is the right way to use it? Where to use it? Where to find the time?
    * Consider this: How much Swift in WWDC 2014 videos? What about 2015?

    View Slide

  15. “Should I learn
    functional programming?”
    9
    * The one overarching question…and its follow up…
    » Let’s consult history…

    View Slide

  16. “Should I learn
    functional programming?”
    “Can you afford not to?”
    9
    * The one overarching question…and its follow up…
    » Let’s consult history…

    View Slide

  17. A little history
    10
    * First came generics (Martin Odersky, Phil Wadler et al.) — based on Standard ML’s
    parametric polymorphism [Phil was one of the main people on the original Haskell
    Committee]
    * Then the rest (Martin Odersky et al.)

    View Slide

  18. A little history
    Generics
    10
    * First came generics (Martin Odersky, Phil Wadler et al.) — based on Standard ML’s
    parametric polymorphism [Phil was one of the main people on the original Haskell
    Committee]
    * Then the rest (Martin Odersky et al.)

    View Slide

  19. A little history
    Closures
    Types inference
    Types systems
    Higher-order
    functions
    Generics
    Pattern matching
    List comprehensions
    Monads etc.
    10
    * First came generics (Martin Odersky, Phil Wadler et al.) — based on Standard ML’s
    parametric polymorphism [Phil was one of the main people on the original Haskell
    Committee]
    * Then the rest (Martin Odersky et al.)

    View Slide

  20. A little history
    Closures
    Types inference
    Types systems
    Higher-order
    functions
    Generics
    Pattern matching
    List comprehensions
    Monads etc.
    11
    * Then the rest (Martin Odersky et al.)
    * Similar situation as with Swift

    View Slide

  21. A little history
    11
    * Then the rest (Martin Odersky et al.)
    * Similar situation as with Swift

    View Slide

  22. 12
    * Java is still big, but…
    * …often the interesting projects are in Scala
    * See companies like Twitter, Atlassian, CBA
    * Big difference: Swift is from same company as the language it succeeds
    * So, I reckon Swift will replace Objective-C much more quickly

    View Slide

  23. 12
    * Java is still big, but…
    * …often the interesting projects are in Scala
    * See companies like Twitter, Atlassian, CBA
    * Big difference: Swift is from same company as the language it succeeds
    * So, I reckon Swift will replace Objective-C much more quickly

    View Slide

  24. scalaz
    Argonaut
    ScalaCheck shapeless
    Monocle
    scodec
    13
    * How Scala is used: fancy Java or adopting FP
    * The questions is, do you want to be part of the conversation?
    » It seems like a good idea to look more closely at FP

    View Slide

  25. “What is the practical benefit of
    functional programming?”
    14
    * There are many success stories (Ericsson, Twitter, Facebook, WhatsApp, and so on)
    * But we want something more concrete…

    View Slide

  26. Less testing!
    15
    * They tell you, more tests are better. That’s actually nonsense. Less tests are better.

    View Slide

  27. 16
    * Common coder wisdom: everything else being equal, it is better to have less code.

    View Slide

  28. Example code courtesy NSHipster (CC BY-NC 4.0): http://nshipster.com/xctestcase/
    17
    * Tests are code (you have to write them, you have to debug them, you have to maintain
    them, you have to run them)

    View Slide

  29. “What if you could gain the
    same confidence in correctness
    with less or simpler tests?”
    18
    * You would spend less time writing, maintaining, and running tests.

    View Slide

  30. Possible states of your application
    19
    * Error states = if you reach such a state, your application will misbehave
    * Tested states = error states shown to be unreachable & valid states shown to be reachable
    * Functional programming aims to statically reduce the possible states
    » How do we get rid of unnecessary states?

    View Slide

  31. Possible states of your application
    Error states
    19
    * Error states = if you reach such a state, your application will misbehave
    * Tested states = error states shown to be unreachable & valid states shown to be reachable
    * Functional programming aims to statically reduce the possible states
    » How do we get rid of unnecessary states?

    View Slide

  32. Possible states of your application
    Error states
    Tested states
    19
    * Error states = if you reach such a state, your application will misbehave
    * Tested states = error states shown to be unreachable & valid states shown to be reachable
    * Functional programming aims to statically reduce the possible states
    » How do we get rid of unnecessary states?

    View Slide

  33. Possible states of your application
    Error states
    Tested states
    19
    * Error states = if you reach such a state, your application will misbehave
    * Tested states = error states shown to be unreachable & valid states shown to be reachable
    * Functional programming aims to statically reduce the possible states
    » How do we get rid of unnecessary states?

    View Slide

  34. Possible states of your application
    Error states
    Tested states
    eliminate
    bugs
    19
    * Error states = if you reach such a state, your application will misbehave
    * Tested states = error states shown to be unreachable & valid states shown to be reachable
    * Functional programming aims to statically reduce the possible states
    » How do we get rid of unnecessary states?

    View Slide

  35. Possible states of your application
    Error states
    Tested states
    eliminate
    bugs
    eliminate
    tests
    19
    * Error states = if you reach such a state, your application will misbehave
    * Tested states = error states shown to be unreachable & valid states shown to be reachable
    * Functional programming aims to statically reduce the possible states
    » How do we get rid of unnecessary states?

    View Slide

  36. Design Rule 1
    Love types
    20
    * We will look at two FP design rules in this talk.
    * Let’s start with types!

    View Slide

  37. “A type signature is worth
    a thousand tests.”
    21
    » Let’s look at a simple example…

    View Slide

  38. @interface MyInventory : NSObject
    @property NSDictionary *inventory;
    - (NSInteger)lookup:(NSString *)item;
    @end
    @implementation MyInventory
    - (instancetype)init {
    self = [super init];
    if (self)
    _inventory = @{@"iPad Air": @10,
    @"MacBook Pro": @3,
    @"iPhone 5S": @7};
    return self;
    }
    - (NSInteger)lookup:(NSString *)item {
    return [(NSNumber *)self.inventory[item])
    integerValue]; }
    @end
    22
    * If we accidentally add a non-numeric value, [-lookup:] will crash.

    View Slide

  39. @interface MyInventory : NSObject
    @property NSDictionary *inventory;
    - (NSInteger)lookup:(NSString *)item;
    @end
    @implementation MyInventory
    - (instancetype)init {
    self = [super init];
    if (self)
    _inventory = @{@"iPad Air": @10,
    @"MacBook Pro": @3,
    @"iPhone 5S": @7};
    return self;
    }
    - (NSInteger)lookup:(NSString *)item {
    return [(NSNumber *)self.inventory[item])
    integerValue]; }
    @end
    @[@7]};
    22
    * If we accidentally add a non-numeric value, [-lookup:] will crash.

    View Slide

  40. class MyInventory {
    let inventory: [String: Int] = ["iPad Air": 10,
    ! ! ! ! ! ! ! ! ! ! ! ! ! "MacBook Pro": 3,
    ! ! ! ! ! ! ! ! ! ! ! ! ! "iPhone 5S": 7]
    func lookup(item: String) -> Int? {
    return inventory[item]
    }
    }
    23
    * How awesome is Swift?!?
    * If we try to add a non-numeric value, we get a type error. (Same if we tried it via a function.)
    * How to test the ObjC version? One test is not sufficient.
    * This is a simple example? What if dict not static? What if value type varies per dict?

    View Slide

  41. class MyInventory {
    let inventory: [String: Int] = ["iPad Air": 10,
    ! ! ! ! ! ! ! ! ! ! ! ! ! "MacBook Pro": 3,
    ! ! ! ! ! ! ! ! ! ! ! ! ! "iPhone 5S": 7]
    func lookup(item: String) -> Int? {
    return inventory[item]
    }
    }
    [7]]
    23
    * How awesome is Swift?!?
    * If we try to add a non-numeric value, we get a type error. (Same if we tried it via a function.)
    * How to test the ObjC version? One test is not sufficient.
    * This is a simple example? What if dict not static? What if value type varies per dict?

    View Slide

  42. class MyInventory {
    let inventory: [String: Int] = ["iPad Air": 10,
    ! ! ! ! ! ! ! ! ! ! ! ! ! "MacBook Pro": 3,
    ! ! ! ! ! ! ! ! ! ! ! ! ! "iPhone 5S": 7]
    func lookup(item: String) -> Int? {
    return inventory[item]
    }
    }
    [7]]
    ⛔️
    dictionary
    type
    23
    * How awesome is Swift?!?
    * If we try to add a non-numeric value, we get a type error. (Same if we tried it via a function.)
    * How to test the ObjC version? One test is not sufficient.
    * This is a simple example? What if dict not static? What if value type varies per dict?

    View Slide

  43. [Key: Value] == Dictionary
    [String: Int] == Dictionary
    24
    * This is not limited to builtin types. You can use the same power in your own definitions.

    View Slide

  44. struct Dictionary
    : CollectionType, DictionaryLiteralConvertible {

    }
    [Key: Value] == Dictionary
    [String: Int] == Dictionary
    24
    * This is not limited to builtin types. You can use the same power in your own definitions.

    View Slide

  45. func i(x: T) -> T {
    return x
    }
    The expressiveness of types
    ???
    25
    * Guess the function! (Assuming no type inspection nor non-termination)
    * Try this with tests.
    * ”Theorems for free!” (aka parametricity)

    View Slide

  46. func i(x: T) -> T {
    return x
    }
    The expressiveness of types
    25
    * Guess the function! (Assuming no type inspection nor non-termination)
    * Try this with tests.
    * ”Theorems for free!” (aka parametricity)

    View Slide

  47. func i(x: T) -> T {
    return x
    }
    func m(f: (T -> U), a: [T]) -> [U] {
    return a.map(f)
    }
    The expressiveness of types
    ???
    25
    * Guess the function! (Assuming no type inspection nor non-termination)
    * Try this with tests.
    * ”Theorems for free!” (aka parametricity)

    View Slide

  48. func i(x: T) -> T {
    return x
    }
    func m(f: (T -> U), a: [T]) -> [U] {
    return a.map(f)
    }
    The expressiveness of types
    25
    * Guess the function! (Assuming no type inspection nor non-termination)
    * Try this with tests.
    * ”Theorems for free!” (aka parametricity)

    View Slide

  49. func i(x: T) -> T {
    return x
    }
    func m(f: (T -> U), a: [T]) -> [U] {
    return a.map(f)
    }
    func r(e: U, f: ((U, T) -> U), a: [T]) -> U {
    return a.reduce(e, combine: f)
    }
    The expressiveness of types
    ???
    25
    * Guess the function! (Assuming no type inspection nor non-termination)
    * Try this with tests.
    * ”Theorems for free!” (aka parametricity)

    View Slide

  50. func i(x: T) -> T {
    return x
    }
    func m(f: (T -> U), a: [T]) -> [U] {
    return a.map(f)
    }
    func r(e: U, f: ((U, T) -> U), a: [T]) -> U {
    return a.reduce(e, combine: f)
    }
    The expressiveness of types
    25
    * Guess the function! (Assuming no type inspection nor non-termination)
    * Try this with tests.
    * ”Theorems for free!” (aka parametricity)

    View Slide

  51. func i(x: T) -> T {
    return x
    }
    func m(f: (T -> U), a: [T]) -> [U] {
    return a.map(f)
    }
    func r(e: U, f: ((U, T) -> U), a: [T]) -> U {
    return a.reduce(e, combine: f)
    }
    The expressiveness of types
    Try this: write a unit test giving the same guarantees
    25
    * Guess the function! (Assuming no type inspection nor non-termination)
    * Try this with tests.
    * ”Theorems for free!” (aka parametricity)

    View Slide

  52. Types let the compiler eliminate (error) states
    26
    * Test frameworks are run less frequently
    * Usually, because they are slow: they typically alway test everything
    * Not bit rot
    » That gets us to the second design rule…

    View Slide

  53. Types let the compiler eliminate (error) states
    Every single time you build

    26
    * Test frameworks are run less frequently
    * Usually, because they are slow: they typically alway test everything
    * Not bit rot
    » That gets us to the second design rule…

    View Slide

  54. Types let the compiler eliminate (error) states
    Every single time you build

    Only checks what changed

    26
    * Test frameworks are run less frequently
    * Usually, because they are slow: they typically alway test everything
    * Not bit rot
    » That gets us to the second design rule…

    View Slide

  55. Types let the compiler eliminate (error) states
    Every single time you build

    Only checks what changed

    ✓ Checked documentation
    26
    * Test frameworks are run less frequently
    * Usually, because they are slow: they typically alway test everything
    * Not bit rot
    » That gets us to the second design rule…

    View Slide

  56. Design Rule 2
    Minimise (mutable) state
    27
    * The second design rule is about managing state differently.

    View Slide

  57. Possible states of your application
    28

    View Slide

  58. Possible states of your application
    Lack of composition
    28

    View Slide

  59. Possible states of your application
    Lack of composition
    Mutable data
    28

    View Slide

  60. Possible states of your application
    Lack of composition
    Interdependent
    data
    Duplicating data
    Mutable data
    28

    View Slide

  61. WWDC 2014, Session 229
    Advanced iOS Application Architecture and Patterns
    29
    * This is a large topic, and it would take too long now to go into much detail.
    * For concrete advice and examples, see this great talk by Andy Matuschak and Colin Barrett
    » Applying these ideas can be tricky…

    View Slide

  62. WWDC 2014, Session 229
    Advanced iOS Application Architecture and Patterns
    Avoid state duplication
    29
    * This is a large topic, and it would take too long now to go into much detail.
    * For concrete advice and examples, see this great talk by Andy Matuschak and Colin Barrett
    » Applying these ideas can be tricky…

    View Slide

  63. WWDC 2014, Session 229
    Advanced iOS Application Architecture and Patterns
    Avoid state duplication
    Use immutable data
    29
    * This is a large topic, and it would take too long now to go into much detail.
    * For concrete advice and examples, see this great talk by Andy Matuschak and Colin Barrett
    » Applying these ideas can be tricky…

    View Slide

  64. M V C
    30
    * Applying these ideas to existing apps can be hard
    * Especially with bloated controllers

    View Slide

  65. M V C
    Kitchen sink
    30
    * Applying these ideas to existing apps can be hard
    * Especially with bloated controllers

    View Slide

  66. M V Citchen sink
    K
    31
    * View owns the view model
    * View model adapts the model to be suitable for presentation
    * View model can be unit tested (independent of views & view controllers)
    * We need AppKit & UIKit controller classes: but keep controllers small

    View Slide

  67. M V C
    V M
    iew odel
    31
    * View owns the view model
    * View model adapts the model to be suitable for presentation
    * View model can be unit tested (independent of views & view controllers)
    * We need AppKit & UIKit controller classes: but keep controllers small

    View Slide

  68. M V C
    V M
    iew odel
    ownership
    31
    * View owns the view model
    * View model adapts the model to be suitable for presentation
    * View model can be unit tested (independent of views & view controllers)
    * We need AppKit & UIKit controller classes: but keep controllers small

    View Slide

  69. M V C
    V M
    iew odel
    adapt model for presentation
    ownership
    31
    * View owns the view model
    * View model adapts the model to be suitable for presentation
    * View model can be unit tested (independent of views & view controllers)
    * We need AppKit & UIKit controller classes: but keep controllers small

    View Slide

  70. M V C
    V M
    iew odel
    adapt model for presentation
    suitable for unit testing
    ownership
    31
    * View owns the view model
    * View model adapts the model to be suitable for presentation
    * View model can be unit tested (independent of views & view controllers)
    * We need AppKit & UIKit controller classes: but keep controllers small

    View Slide

  71. M V C
    V M
    iew odel
    &C
    adapt model for presentation
    suitable for unit testing
    ownership
    31
    * View owns the view model
    * View model adapts the model to be suitable for presentation
    * View model can be unit tested (independent of views & view controllers)
    * We need AppKit & UIKit controller classes: but keep controllers small

    View Slide

  72. Possible states of your application
    32
    * Immutable models in Swift using structs, enums & classes with readonly properties (lets)

    View Slide

  73. Possible states of your application
    simple relationship between
    view state and the state of the
    view model

    32
    * Immutable models in Swift using structs, enums & classes with readonly properties (lets)

    View Slide

  74. Possible states of your application
    simple relationship between
    view state and the state of the
    view model

    (parts of the) model can be
    immutable

    32
    * Immutable models in Swift using structs, enums & classes with readonly properties (lets)

    View Slide

  75. struct Project {
    let name: String
    let image: UIImage
    let canvas: Canvas
    let url: NSURL
    // Create empty project
    init(name: String)
    // Create project for image at URL
    init(url: NSURL)
    // Create project from image for fixed URL
    init(image: UIImage, name: String, url: NSURL)
    // Rename project
    func rename(name: String) -> Project
    // Remove project backing file
    func remove()
    }
    33
    * No aliasing to worry about
    * Tests don’t depend on context (except the file system — which is global mutable state)
    * Cf. blog post by Alexandros Salazar: http://nomothetis.svbtle.com/immutable-swift

    View Slide

  76. types >< state
    Questions to ask
    How can I use types to eliminate tests?
    How can I minimise state to eliminate tests?
    34
    » For some more background on the universal nature of FP…

    View Slide

  77. “Do Extraterrestrials Use
    Functional Programming?”
    https://speakerdeck.com/mchakravarty/do-extraterrestrials-use-functional-programming
    2013
    35
    * YOW! Lambda Jam 2013 keynote
    * Annual conference on functional programming for developers in Australia

    View Slide

  78. Thank you!
    36

    View Slide

  79. "Nile blue 05" by Kuebi = Armin Kübelbeck - Own work. CC BY-SA 3.0 - http://commons.wikimedia.org/wiki/File:Nile_blue_05.jpg
    Images from
    http://wikimedia.org
    http://openclipart.org
    37

    View Slide