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

704056da9a4c4e075ad14479beaebab7?s=47 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

704056da9a4c4e075ad14479beaebab7?s=128

takasek

March 19, 2019
Tweet

Transcript

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

    Pre Talks 2019 1
  2. takasek @takasek Works OSS: ActionClosurable౳ App: PasteTheType Articles ʮίϯύΠϧΤϥʔ΍ϥϯλΠϜΤϥʔΛ௚͍ͯ͘͠ ͚ͩͰiOSΞϓϦͷ࡞Γํ͕Θ͔ΔϓϩδΣΫτʯ

    ʮ͓લΒ͕ModelͱݺͿΞϨΛͳΜͱݺͿ΂͖͔ʯ ʮiOSΞϓϦઃܭύλʔϯೖ໳ʯʢڞஶʣ 2
  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
  4. Continuation- Passing Style (CPS) 4

  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
  6. ! 6

  7. func doSomething( i: Int, completion: @escaping (String) -> Void )

    This interface isn't the best 7
  8. ʮI know what you meanʯ 8

  9. ʮAbout Callback Hell, huh?ʯ 9

  10. Nop. 10

  11. Design By Contract 11

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

    by Bertrand Meyer 12
  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
  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
  15. Swifty type system helps Design by Contract. 15

  16. By the way, 16

  17. func half(of i: Int) throws -> Int { if !i.isMultiple(of:

    2) { throw Error.isOdd } return i / 2 } translate it to CPS. 17
  18. func half(of i: Int, completion: (Int) -> Void) { if

    !i.isMultiple(of: 2) { return } completion(i / 2) } 18
  19. 19

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

  21. 21

  22. Not called...? 22

  23. 23

  24. completion hadn't be called 24

  25. func half(of i: Int, completion: (Int) -> Void) { if

    !i.isMultiple(of: 2) { return // ! } completion(i / 2) } 25
  26. enum Result<T> { case success(T) case error(Error) } func half(of

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

    i: Int, completion: (Result<Int>) -> Void) { if !i.isMultiple(of: 2) { completion(.error(.isOdd)) // } completion(.success(i / 2)) } 27
  28. Okay, check again! 28

  29. 29

  30. Called twice...? 30

  31. func half(of i: Int, completion: (Result<Int>) -> Void) { if

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

    !i.isMultiple(of: 2) { completion(.error(.isOdd)) return // ! } completion(.success(i / 2)) } 32
  33. CPS avoids benefits of Static Typing 33

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

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

  36. func half(of i: Int) -> RxSwift.Single<Int> { if !i.isMultiple(of: 2)

    { return .error(Error.isOdd) } return .just(i / 2) } ͜ΕͳΒ੩తܕ෇͚ͷԸܙΛड͚ͭͭɺ ʮඇಉظͰ͋Δ͜ͱʯΛදݱͰ͖Δ 36
  37. • Promise(Future) ύλʔϯ • PromiseK • Hydra • RxSwift •

    etc • async/await • comming soon in Swift 5.x!? • ͜ͷݴޠ࢓༷Λϕʔεʹ Future ܕΛߏஙՄೳ CPSΛશ໘తʹஔ͖͔͑Մೳ͔ͱ͍͏ͱ೉͍͕͠ɺ બ୒ࢶΛ஌ͬͨ͏͑ͰύλʔϯΛબͼ͍ͨ 37
  38. ݁࿦ ɾਓؒ͸ϛεΛ͠·͢ ɾϛεΛ͢Δલʹɺ ද໌ΛίϯύΠϥ͕෼͔ΔܗͰॻ͚ͳ͍͔ ҙࣝ͠ͳ͕Βઃܭ͠·͠ΐ͏ 38

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

  40. ʮද໌ʯʹ͍ͭͯͷิ଍ • Ҿ਺ɾ໭Γ஋ͷܕ͚͕ͩද໌Ͱ͸ͳ͍ͱݴ͚ͬͨΕͲ… • assert ͚ͩͰͳ͘ɺSwiftͰݴ͑͹ generics ΍ conditional conformance΋ද໌ͷํ๏

    • ΂ͭʹɺίϯύΠϥղऍෆೳͳද໌͸ྑ͘ͳ͍…Θ͚Ͱ͸ͳ͍ • දݱྗΛ্͛Δͱֶशίετɾෳࡶੑ͕ϖΠ͠ͳ͍͜ͱ΋ଟ͍ͷͰɺͦ͜͸όϥϯε • ͨͱ͑͹ɺڽͬͨprotocolͷwhere۟ɺৗਓʹཧղग़དྷΔ͔ͬͯݴΘΕΔͱݫ͍͠ΑͶ… ɹ 40
  41. ิ଍ͷิ଍ ٯʹݴ͑͹ɺ ܖ໿ʹΑΔઃܭ͸ ݴޠΛ໰Θͣద༻Մೳͳ֓೦Ͱ͢ t_wada͞ΜʹΑΔ ͋͑ͯPHPΛϕʔεʹͨ͠εϥΠυ PHPer͡Όͳͯ͘΋ΦεεϝͰ͢ https://speakerdeck.com/twada/php- conference-2016 41

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

    44