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

SwiftでElmを作る (Japanese)

SwiftでElmを作る (Japanese)

try! Swift Tokyo 2017 Aftershow (Mar 7, 2017)
https://cyberagent.connpass.com/event/50584/

Library: https://github.com/inamiy/SwiftElm

Eac0bf787b5279aca5e699ece096956e?s=128

Yasuhiro Inami

March 07, 2017
Tweet

Transcript

  1. SwiftͰ ElmΛ࡞Δ 2017/03/07 try! Swift AfterShow #tryswift_as Yasuhiro Inami /

    @inamiy
  2. None
  3. Elm?

  4. ElmͬͯԿ? • WebΞϓϦ༻ͷؔ਺ܕϓϩάϥϛϯάݴޠ • Haskell෩ͷߏจ͔ΒɺHTML/CSS/JavaScriptΛੜ੒ • ७ਮؔ਺ܕɺ੩తܕ෇͚ɺਖ਼֨ධՁ • ܕΫϥε΍FRP͕ͳ͍ →

    ॳ৺ऀͰ΋ཧղ͠΍͍͢ • Virtual DOM ͱ Effect Manager Λѻ͏ • React.js + Redux.jsΑΓ΋γϯϓϧ
  5. main = Html.beginnerProgram { model = 0, view = view,

    update = update } type Msg = Increment | Decrement update msg model = case msg of Increment -> model + 1 Decrement -> model - 1 view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ]
  6. let program = BeginnerProgram(model: 0, view: view, update: update) ...

    enum Msg { case increment, decrement } func update(msg: Msg, model: Model) -> Model { switch msg { case .increment: return model + 1 case .decrement: return model - 1 } } func view(model: Model) -> Html<Msg> { return div(children: [ button(attributes: [onClick(.decrement)], children: [text("-")]), div(children: [text("\(model)")]), button(attributes: [onClick(.increment)], children: [text("+")]) ]) }
  7. None
  8. Swift࣮૷Ͱඞཁͳ΋ͷ • Virtual DOM • State Machine (+ Effect Manager)

    • In Depth • Template Metaprogramming • Equatable Function • Flexbox layout
  9. Virtual DOM

  10. Virtual DOM • Viewͷdiff-patchΞϧΰϦζϜ • ΞϓϦͷঢ়ଶ͕มΘΔ౓ʹ"ޮ཰తͳ"࠶ඳըΛߦ͏ • ྫɿElm, React.js, Vue.jsͳͲ

    • https://github.com/inamiy/VTree • func diff(old: VTree, new: VTree) -> Patch • func apply(patch: Patch, to: UIView) -> UIView?
  11. VTree (ٙࣅίʔυ) protocol VTree { ... var children: [VTree] {

    get } func createView() -> UIView } struct VView: VTree { ... } func render(model: Model) -> VTree { return VView(children: [VLabel(text: "\(model)")]) }
  12. VTree (ٙࣅίʔυ) var model = 0 var tree = render(model)

    var view = tree.createView() timer(1) { model += 1 let newTree = render(model) let patch = diff(old: tree, new: newTree) view = apply(patch: patch, to: view) }
  13. State Machine (+ Effect Manager)

  14. State Machine (+ Effect Manager) • ʮΞϓϦͷঢ়ଶ (Model)ʯΛ؅ཧ͠ɺʮೖྗ (Msg)ʯ͕ߦΘΕ Δ౓ʹʮঢ়ଶભҠؔ਺

    (update)ʯ Λ௨ͯ͠ʮঢ়ଶมߋʯͱ ʮ෭࡞༻ (Cmd)ʯΛಉ࣌ʹѻ͏ • initial: Model (+ Cmd<Msg>) • update: (Msg) -> (Model) -> Model (+ Cmd<Msg>) • update͸७ਮؔ਺
  15. State Machine (+ Effect Manager) • ͭ·ΓɺϛʔϦɾϚγϯ (Mealy Machine) •

    Redux.jsͷݪܕ • https://github.com/inamiy/ReactiveAutomaton • iOSDC Japan 2016 • iOSConf SG 2016
  16. VTree + Automaton

  17. SwiftElm https://github.com/inamiy/SwiftElm

  18. In Depth

  19. Template Metaprogramming • krzysztofzablocki/Sourcery • SourceKitten (AST parser) ͱ Stencil

    (template) Λ࢖༻ • ৑௕ίʔυΛ࡟ݮ • AutoEquatable, AutoHashable, AutoCases, AutoLenses, Auto-LinuxMain.swift, ͳͲ • ʮSwiftElm → ར༻ଆʯ΁ͷ(Ҿ਺෇͖)ϝοηʔδϯάʹ࢖༻
  20. Equatable Function • dankogai/peekFunc ✨"✨ func peekFunc<A, R>(_ f: (A)

    -> R) -> (fp: Int, ctx: Int) { let (_, low) = unsafeBitCast(f, to: (Int, Int).self) let offset = MemoryLayout<Int>.size == 8 ? 16 : 12 let ptr = UnsafePointer<Int>(bitPattern: low + offset) return (ptr!.pointee, ptr!.successor().pointee) } • Msg ஋ίϯετϥΫλΛൺֱ͢Δࡍʹศར • ͞Βʹؔ਺ΛFuncBox<A, R>ܕͰϥοϓͯ͠ɺಉҰੑΛอূ
  21. Flexbox • inamiy/Flexbox • facebook/yoga ͷSwiftϥούʔ • ΫϩεϓϥοτϑΥʔϜͷ CSS Flexbox

    ϨΠΞ΢τΤϯδϯ • ReactNativeͰ΋࢖ΘΕ͍ͯΔ • ඇಉظܭࢉ͕Մೳ • UIStackViewҎ্ͷ͜ͱ͕Ͱ͖Δ • AutoLayoutΑΓ΋؆୯ʢ͔΋ʣ
  22. ·ͱΊ • VTree (Virtual DOM) • ReactiveAutomaton (State Machine) •

    Sourcery (Template Metaprogramming) • dankogai/peekFunc (Function Equality) • facebook/yoga (Layout Engine) • SwiftElm !
  23. None
  24. Thanks!