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 Slide

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

    View 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 Slide

  4. Continuation-
    Passing Style
    (CPS)
    4

    View 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 Slide

  6. !
    6

    View Slide

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

    View Slide

  8. ʮI know what you meanʯ
    8

    View Slide

  9. ʮAbout Callback Hell, huh?ʯ
    9

    View Slide

  10. Nop.
    10

    View Slide

  11. Design
    By Contract
    11

    View Slide

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

    View Slide

  13. 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 Slide

  14. 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 Slide

  15. Swifty type system helps Design by Contract.
    15

    View Slide

  16. By the way,
    16

    View Slide

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

    View Slide

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

    View Slide

  19. 19

    View Slide

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

    View Slide

  21. 21

    View Slide

  22. Not called...?
    22

    View Slide

  23. 23

    View Slide

  24. completion
    hadn't be called
    24

    View Slide

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

    View Slide

  26. 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 Slide

  27. 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 Slide

  28. Okay, check again!
    28

    View Slide

  29. 29

    View Slide

  30. Called twice...?
    30

    View Slide

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

    View Slide

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

    View Slide

  33. CPS avoids
    benefits of
    Static Typing
    33

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  42. ʮܧଓ౉͠ʯʹ͍ͭͯͷิ଍
    • ࣮͸ 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 Slide

  43. 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 Slide

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

    View Slide