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

Continuation-Passing Style and Design By Contract(English ver.) / 20190319(E) #tryswift_pre

takasek
March 19, 2019

Continuation-Passing Style and Design By Contract(English ver.) / 20190319(E) #tryswift_pre

Presentation in
【増枠/increase】try! Swift Pre Talks 2019 - connpass
https://tryswifttokyo-aftertalks.connpass.com/event/120987/

Japanese ver.
https://speakerdeck.com/takasek/20190319-number-tryswift-pre

takasek

March 19, 2019
Tweet

More Decks by takasek

Other Decks in Programming

Transcript

  1. Continuation-Passing Style and Design
    By Contract
    by.
    2019/3/19 try! Swift Pre Talks 2019
    1

    View full-size slide

  2. takasek
    @takasek
    Works
    OSS: ActionClosurable౳
    App: PasteTheType
    Articles
    ʮίϯύΠϧΤϥʔ΍ϥϯλΠϜΤϥʔΛ௚͍ͯ͘͠
    ͚ͩͰiOSΞϓϦͷ࡞Γํ͕Θ͔ΔϓϩδΣΫτʯ
    ʮ͓લΒ͕ModelͱݺͿΞϨΛͳΜͱݺͿ΂͖͔ʯ
    ʮiOSΞϓϦઃܭύλʔϯೖ໳ʯʢڞஶʣ
    2

    View full-size slide

  3. ʮiOSΞϓϦઃܭύλʔϯೖ໳ʯ
    ON SALE!!
    https://peaks.cc/takasek/iOS_architecture
    takasek୲౰ষ
    Chap 1ʮTo designʯ
    Chap 2ʮBefore applying patterns to your
    designʯ
    Chap 3ʮDesigning swiftyʯ
    Chap 4ʮOverview through history of
    architecturesʯ
    3

    View full-size slide

  4. Continuation-
    Passing Style
    (CPS)
    4

    View full-size slide

  5. // Without CPS
    func doSomething(i: Int) -> String {
    sleep(100)
    return "\(i)"
    }
    // With CPS
    func doSomething(i: Int, completion: @escaping (String) -> Void) {
    DispatchQueue.global().async {
    sleep(100)
    completion("\(i)")
    }
    }
    5

    View full-size slide

  6. func doSomething(
    i: Int,
    completion: @escaping (String) -> Void
    )
    This interface isn't the best
    7

    View full-size slide

  7. ʮI know what you meanʯ
    8

    View full-size slide

  8. ʮAbout Callback Hell, huh?ʯ
    9

    View full-size slide

  9. Design
    By Contract
    11

    View full-size slide

  10. Design By Contract
    The idea to construct reliable
    system
    introduced by Bertrand Meyer
    12

    View full-size slide

  11. Design By Contract
    Asserts;
    • Preconditionɿ
    a caller should ensure it.
    described by Argument Type or so on.
    • Postconditionɿ
    a callee should ensure it.
    described by Return Type or so on.
    If precondition is violated, throw Exception.
    13

    View full-size slide

  12. For example,
    func half(of i: Int) throws -> Int {
    assert(i.isMultiple(of: 2))
    if !i.isMultiple(of: 2) { throw Error.isOdd }
    return i / 2
    }
    • Precondition:
    • accepts Int.
    • accepts Even. (not describable as type)
    • Postcondition: returns Int.
    • Exception: thrown if the argument is odd.
    14

    View full-size slide

  13. Swifty type system helps Design by Contract.
    15

    View full-size slide

  14. By the way,
    16

    View full-size slide

  15. func half(of i: Int) throws -> Int {
    if !i.isMultiple(of: 2) {
    throw Error.isOdd
    }
    return i / 2
    }
    translate it to CPS.
    17

    View full-size slide

  16. func half(of i: Int, completion: (Int) -> Void) {
    if !i.isMultiple(of: 2) {
    return
    }
    completion(i / 2)
    }
    18

    View full-size slide

  17. OK, in the case of Odd
    value...?
    20

    View full-size slide

  18. Not called...?
    22

    View full-size slide

  19. completion
    hadn't be called
    24

    View full-size slide

  20. func half(of i: Int, completion: (Int) -> Void) {
    if !i.isMultiple(of: 2) {
    return //
    !
    }
    completion(i / 2)
    }
    25

    View full-size slide

  21. enum Result {
    case success(T)
    case error(Error)
    }
    func half(of i: Int, completion: (Result) -> Void) {
    if !i.isMultiple(of: 2) {
    return //
    !
    }
    completion(.success(i / 2))
    }
    26

    View full-size slide

  22. enum Result {
    case success(T)
    case error(Error)
    }
    func half(of i: Int, completion: (Result) -> Void) {
    if !i.isMultiple(of: 2) {
    completion(.error(.isOdd)) //
    }
    completion(.success(i / 2))
    }
    27

    View full-size slide

  23. Okay, check again!
    28

    View full-size slide

  24. Called twice...?
    30

    View full-size slide

  25. func half(of i: Int, completion: (Result) -> Void) {
    if !i.isMultiple(of: 2) {
    completion(.error(.isOdd))
    //
    !
    }
    completion(.success(i / 2))
    }
    31

    View full-size slide

  26. func half(of i: Int, completion: (Result) -> Void) {
    if !i.isMultiple(of: 2) {
    completion(.error(.isOdd))
    return //
    !
    }
    completion(.success(i / 2))
    }
    32

    View full-size slide

  27. CPS avoids
    benefits of
    Static Typing
    33

    View full-size slide

  28. ͳͥͳͷ͔
    ໭Γ஋ͷܕʹΑͬͯ
    ࣄޙ৚݅ΛදݱͰ͖ͳ͍͔Β
    (T, (U) -> Void) -> Void
    Void͸࠷ऑͷࣄޙ৚݅
    34

    View full-size slide

  29. Ͳ͏͢Ε͹͍͍͔
    ໭Γ஋ͷܕʹΑͬͯ
    ࣄޙ৚݅Λදݱ͢Ε͹͍͍
    (T) -> XXX
    ʮ͍ͣΕ݁Ռ͕ಘΒΕΔʯ͜ͱΛܕ෇͚ͰࣔͤΕ͹ɺ
    ඇಉظॲཧͰ΋໭Γ஋Λػೳͤ͞ΒΕΔ
    35

    View full-size slide

  30. func half(of i: Int) -> RxSwift.Single {
    if !i.isMultiple(of: 2) {
    return .error(Error.isOdd)
    }
    return .just(i / 2)
    }
    ͜ΕͳΒ੩తܕ෇͚ͷԸܙΛड͚ͭͭɺ
    ʮඇಉظͰ͋Δ͜ͱʯΛදݱͰ͖Δ
    36

    View full-size slide

  31. • Promise(Future) ύλʔϯ
    • PromiseK
    • Hydra
    • RxSwift
    • etc
    • async/await
    • comming soon in Swift 5.x!?
    • ͜ͷݴޠ࢓༷Λϕʔεʹ Future ܕΛߏஙՄೳ
    CPSΛશ໘తʹஔ͖͔͑Մೳ͔ͱ͍͏ͱ೉͍͕͠ɺ
    બ୒ࢶΛ஌ͬͨ͏͑ͰύλʔϯΛબͼ͍ͨ
    37

    View full-size slide

  32. ݁࿦
    ɾਓؒ͸ϛεΛ͠·͢
    ɾϛεΛ͢Δલʹɺ
    ද໌ΛίϯύΠϥ͕෼͔ΔܗͰॻ͚ͳ͍͔
    ҙࣝ͠ͳ͕Βઃܭ͠·͠ΐ͏
    38

    View full-size slide

  33. ͓·͚
    ͱͯ΋5෼Ͱ͸ޠΓ͖Εͳ͍࿩
    39

    View full-size slide

  34. ʮද໌ʯʹ͍ͭͯͷิ଍
    • Ҿ਺ɾ໭Γ஋ͷܕ͚͕ͩද໌Ͱ͸ͳ͍ͱݴ͚ͬͨΕͲ…
    • assert ͚ͩͰͳ͘ɺSwiftͰݴ͑͹ generics ΍ conditional conformance΋ද໌ͷํ๏
    • ΂ͭʹɺίϯύΠϥղऍෆೳͳද໌͸ྑ͘ͳ͍…Θ͚Ͱ͸ͳ͍
    • දݱྗΛ্͛Δͱֶशίετɾෳࡶੑ͕ϖΠ͠ͳ͍͜ͱ΋ଟ͍ͷͰɺͦ͜͸όϥϯε
    • ͨͱ͑͹ɺڽͬͨprotocolͷwhere۟ɺৗਓʹཧղग़དྷΔ͔ͬͯݴΘΕΔͱݫ͍͠ΑͶ…
    ɹ
    40

    View full-size slide

  35. ิ଍ͷิ଍
    ٯʹݴ͑͹ɺ
    ܖ໿ʹΑΔઃܭ͸
    ݴޠΛ໰Θͣద༻Մೳͳ֓೦Ͱ͢
    t_wada͞ΜʹΑΔ
    ͋͑ͯPHPΛϕʔεʹͨ͠εϥΠυ
    PHPer͡Όͳͯ͘΋ΦεεϝͰ͢
    https://speakerdeck.com/twada/php-
    conference-2016
    41

    View full-size slide

  36. ʮܧଓ౉͠ʯʹ͍ͭͯͷิ଍
    • ࣮͸ async/await͸ʮ಺෦తͳCPSม׵ʯͦͷ΋ͷͱ͍͑·͢
    Continuation Passing Style Revisited
    – Fabulous Adventures In Coding
    https://blogs.msdn.microsoft.com/ericlippert/2010/10/21/
    continuation-passing-style-revisited-part-one/
    ͦͷ࿨༁
    matarillo.com: ܧଓ౉͠ελΠϧ(CPS)ͱඇಉظߏจ(async/await)
    https://matarillo.com/general/cps
    42

    View full-size slide

  37. Swiftͷ async/await ͱ
    ܧଓͱ Future ͷؔ܎
    Chris Lattnerͷproposal2ʹΑΔͱɺ
    • ଞͷݴޠͰ͸ Future ͕·ͣ͋ͬͯɺͦͷ্ʹasync/await͕৐͔͍ͬͬͯΔ
    • Swiftͷasync/awaitͷઃܭͰ͸ͦΕΛલఏͱ͸ͤͣɺܧଓΛͦͷ··ѻ͏खஈΛ࿐ग़͍ͤͯ͞
    Δ
    • ͱ͸͍͑ Future ͱ͍͏ܕ෇͚͞Εͨঢ়ଶͰѻ͏ΠϯλϑΣʔε΋ߏஙՄೳͰ͢Αɺͱ͍͏͜ͱ
    2 https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619
    yimajo͞Μͷʮasync/awaitݚڀಡຊʯ΋͋ΘͤͯͲ͏ͧ
    43

    View full-size slide

  38. ؔ࿈ɿʮܖ໿ʹΑΔઃ
    ܭʯΛΩʔϫʔυͰ֦
    ு͢Δ࿩
    ʮܖ໿ʹΑΔઃܭʯʹ͍ͭͯৄղ͞Ε
    ͍ͯΔʮΦϒδΣΫτࢦ޲ೖ໳ʯʹ
    ͸ɺ
    ඇಉظʢฒߦʣॲཧΛ΋ͱʹ֦ுͨ͠
    ৔߹ͷܖ໿ͷϙϦγʔʹ͍ͭͯͷٞ࿦
    ΋͋Γ·͢
    ໘ന͍Αʂ
    44

    View full-size slide