{ let model: MyModelProtocol let subview: MySubView init(model: MyModelProtocol) { self.model = model // retained by ARC self.subview = MySubView(model: model) // pass model ... } } let model = MyModel(...) let view1 = MyView1(model: model) // pass model let view2 = MyView2(model: model) // pass model ... // pass, pass, pass... (manually)
stateful DOM • Virtual DOM: Efficient diff-patch algorithm • Redux: Singleton state container • Reducer: State transition using pure function • Middleware: Generates side-effect • Action, Reducer, and Middleware defines app's domain • Popular as a functional programming approach
HTML/CSS/JavaScript • Purely functional, static typing, strict evaluation • No typeclass (protocol) nor FRP = easy to understand • Uses Virtual DOM & Effect Manager • Unidirectional dataflow known as Elm Architecture
own state (no setState) • manage lifecycle (no componentDidMount) • Redux is already built-in (Effect Manager) • Better effect handling inside pure "update (reducer)", not "middleware" • Typed (no propTypes validation)
key: Key? { get } // for efficient reordering var props: [String: Any] { get } // can be mapped by Mirror & KVC var propsKeysForMeasure: [String] { get } // for flexbox measurement var flexbox: Flexbox.Node? { get } // for view layout var handlers: HandlerMapping<MsgType> { get } // e.g. target-action var gestures: [GestureEvent<MsgType>] { get } var children: [AnyVTree<MsgType>] { get } func createView<Msg2: Message>(_ msgMapper: @escaping (MsgType) -> Msg2) -> ViewType } class AnyVTree<Msg: Message>: VTree { ... } // type-erasure
(Msg) via state-transition function (update) that may include additional side-effect (Cmd) • That is, Mealy Machine (transducer) • A prototype of Redux since 1955 • Expressed as 6-tuple (Σ, Ω, S, s0, δ, λ)
(model, Cmd msg) , update : msg -> model -> (model, Cmd msg) , subscriptions : model -> Sub msg , view : model -> Html msg } -> Program Never model msg "update" has (almost) the same type as (Σ, S) -> (S, Ω)