* [Caml-list] Announce: ocaml-vdom (pre-release) @ 2016-11-30 16:52 Alain Frisch 2016-11-30 19:22 ` Yaron Minsky ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Alain Frisch @ 2016-11-30 16:52 UTC (permalink / raw) To: ocsigen, OCaml Mailing List Dear all, You might be interested in the ocaml-vdom project which has been used by LexiFi for some time and open-sourced recently. It contains two components which we use to create our browser-side UIs with js_of_ocaml and which might be useful to the community: - Bindings to the DOM and other browser APIs, implemented with gen_js_api. (Partial bindings, expanded on demand.) - An implementation of a "virtual DOM" and the "Elm architecture", i.e. a programming model where the UI is specified by a state type, a view function (producing a functional version of the DOM), and an update function that modifies the state based on messages (generated by UI events or external interactions). Project page: https://github.com/LexiFi/ocaml-vdom -- Alain ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-11-30 16:52 [Caml-list] Announce: ocaml-vdom (pre-release) Alain Frisch @ 2016-11-30 19:22 ` Yaron Minsky 2016-12-01 9:32 ` Alain Frisch 2016-11-30 22:46 ` Martin DeMello [not found] ` <CAG+nEjzO1qFfxHSMqueiKcTJyJYnREmvXhzGR7H+noBmV2oUKw@mail.gmail.com> 2 siblings, 1 reply; 12+ messages in thread From: Yaron Minsky @ 2016-11-30 19:22 UTC (permalink / raw) To: Alain Frisch; +Cc: ocsigen, OCaml Mailing List Alain, this looks awesome! We'll take a look at this and maybe use it instead of the javascript library we're currently depending on here: https://github.com/janestreet/virtual_dom I'm curious if you have any story for making the recomputation of the virtual-dom itself more efficient. Right now, we're using incremental for this part of the story, as reflected here: https://github.com/janestreet/incr_dom That said, for small UIs, this kind of incrementality is less important, so whether this is worth doing may depend on your applications. y On Wed, Nov 30, 2016 at 11:52 AM, Alain Frisch <alain.frisch@lexifi.com> wrote: > Dear all, > > You might be interested in the ocaml-vdom project which has been used by > LexiFi for some time and open-sourced recently. It contains two components > which we use to create our browser-side UIs with js_of_ocaml and which might > be useful to the community: > > - Bindings to the DOM and other browser APIs, implemented with > gen_js_api. (Partial bindings, expanded on demand.) > > - An implementation of a "virtual DOM" and the "Elm architecture", i.e. a > programming model where the UI is specified by a state type, a view function > (producing a functional version of the DOM), and an update function that > modifies the state based on messages (generated by UI events or external > interactions). > > > Project page: > > https://github.com/LexiFi/ocaml-vdom > > > -- Alain > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-11-30 19:22 ` Yaron Minsky @ 2016-12-01 9:32 ` Alain Frisch 2016-12-01 22:18 ` Yaron Minsky 0 siblings, 1 reply; 12+ messages in thread From: Alain Frisch @ 2016-12-01 9:32 UTC (permalink / raw) To: Yaron Minsky; +Cc: ocsigen, OCaml Mailing List Hi Yaron, On 30/11/2016 20:22, Yaron Minsky wrote: > I'm curious if you have any story for making the recomputation of the > virtual-dom itself more efficient. > ... > That said, for small UIs, this kind of incrementality is less > important, so whether this is worth doing may depend on your > applications. Our story w.r.t. updating the vdom itself is the same as Elm, I believe: 1. In the vast majority of cases, the mapping from the "state" to the vdom is very quick and it is ok to recompute the full vdom on every state change. An argument often made in the vdom space is that a UI usable by human-beings cannot possibly have a very big DOM (moreover, even recent browsers such as the latest Edge or Firefox struggle with tables starting at a few thousands rows), and that computing the full vdom "cannot be that costly". I don't want to enter such discussion here, but in our own use cases, we indeed try to avoid "overly big UIs" and we don't have strong performance requirements such as continuous streams of updates pushed by the server; if it takes 10ms to react on a user UI event, it is perfectly fine for our case. My intuition is that most applications would be a similar situation, but I appreciate that you have very different kinds of UIs and performance constraints that require a more incremental approach. 2. The library provides: val memo: ?key:string -> ('a -> 'msg vdom) -> 'a -> 'msg vdom (** Apply the function to generate a VDOM tree only if the function or its argument have changed (physically) from the previous synchronization. *) (similar to Elm's Lazy: http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Lazy ) This is typically used when embedding the view of a "sub-component" derived from only part of the our current state. If we can ensure this sub-part remains the same, the previous vdom (at the same "site") is reused, which skips both the vdom generation and the vdom diffing. Typically, the generation function would be a toplevel declaration (so it will always be the same, physically) and we arrange to avoid touching the part of the global state on which it depends. Of course, it is also possible to use any other mechanism (such a memoization table) to reuse previously computed vdoms. > Another thought: you might want to consider the design we used for our > wrapper on Matt Esch's virtual-dom library. In particular, in our > design we don't need a type-parameter for vdom nodes determining the > type of a message, and we don't need the corresponding map > functions. Instead, we use open types and a registration and dispatch > mechanism for values thus injected. Thanks for the hint. Do you have pointers to code examples using the "inject" function? It seems to me that you will need to apply to it produce any "message" in the view function. In our library, you can write directly: input "+" ~a:[value "+"; type_button; onclick `Plus] With the "inject" approach, do you need to write it like: input "+" ~a:[value "+"; type_button; onclick (inject `Plus)] ? If so, this does not seem strictly lighter than using the "map" function occasionally. Moreover this seems to open the door to possible problems if a vdom fragment producing some kinds of messages is injected in a "host application" that cannot process these messages. It also means that one needs to take the identity of the "inject" function itself into account in order to memoize vdom-generation functions. Basically, we need "map" on "component boundaries", and even not always, since components can take ad hoc injection functions to wrap their messages into their "host" own message type (as the SelectionList example in https://github.com/LexiFi/ocaml-vdom/blob/master/examples/vdom_ui.mli ). The library does use extensible types (with a registration/dispatch mechanism) in two other places, though: - "Commands" (encapsulation of side-effectul operations). The set of "command constructors" is small and has a global nature (e.g. "AJAX query", "timer", etc), while the type of "messages" is specific to each application and component. - "Custom nodes" in the VDOM which allow plugging "native" components (again, the set of such possible components is more "fixed" than messages). Alain ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-12-01 9:32 ` Alain Frisch @ 2016-12-01 22:18 ` Yaron Minsky 0 siblings, 0 replies; 12+ messages in thread From: Yaron Minsky @ 2016-12-01 22:18 UTC (permalink / raw) To: Alain Frisch; +Cc: ocsigen, OCaml Mailing List On Thu, Dec 1, 2016 at 4:32 AM, Alain Frisch <alain.frisch@lexifi.com> wrote: > Hi Yaron, > > On 30/11/2016 20:22, Yaron Minsky wrote: >> >> I'm curious if you have any story for making the recomputation of the >> virtual-dom itself more efficient. > >> ... >> >> That said, for small UIs, this kind of incrementality is less >> important, so whether this is worth doing may depend on your >> applications. > > > Our story w.r.t. updating the vdom itself is the same as Elm, I believe: > > 1. In the vast majority of cases, the mapping from the "state" to the vdom > is very quick and it is ok to recompute the full vdom on every state change. > > An argument often made in the vdom space is that a UI usable by human-beings > cannot possibly have a very big DOM (moreover, even recent browsers such as > the latest Edge or Firefox struggle with tables starting at a few thousands > rows), and that computing the full vdom "cannot be that costly". I don't > want to enter such discussion here, but in our own use cases, we indeed try > to avoid "overly big UIs" and we don't have strong performance requirements > such as continuous streams of updates pushed by the server; if it takes 10ms > to react on a user UI event, it is perfectly fine for our case. My > intuition is that most applications would be a similar situation, but I > appreciate that you have very different kinds of UIs and performance > constraints that require a more incremental approach. I do think for even moderate size views of data (big tables, graphs, etc.) this argument stops working pretty quickly, but I agree there is a large scope of applications for which this is true. It's worth noting that we use Incremental to pull off what we've called "partial rendering", which is to render a table with, say, 10k rows, but only actually rendering the 60 or so that are actually in view. This makes what would otherwise be rather sluggish applications quite zippy. > 2. The library provides: > > val memo: ?key:string -> ('a -> 'msg vdom) -> 'a -> 'msg vdom > (** Apply the function to generate a VDOM tree only if the function > or its argument have changed (physically) from the previous > synchronization. *) > > (similar to Elm's Lazy: > http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Lazy ) > > This is typically used when embedding the view of a "sub-component" derived > from only part of the our current state. If we can ensure this sub-part > remains the same, the previous vdom (at the same "site") is reused, which > skips both the vdom generation and the vdom diffing. Typically, the > generation function would be a toplevel declaration (so it will always be > the same, physically) and we arrange to avoid touching the part of the > global state on which it depends. > > Of course, it is also possible to use any other mechanism (such a > memoization table) to reuse previously computed vdoms. One downside of the Elm style approach is that physical equality is brittle, e.g., if you end up constructing something that's logically but not physically equal, you can end up recomputing a lot more than you might have expected. I do think making it possible to add a custom equality function makes this a bit better, and is an easy change to make. >> Another thought: you might want to consider the design we used for our >> wrapper on Matt Esch's virtual-dom library. In particular, in our >> design we don't need a type-parameter for vdom nodes determining the >> type of a message, and we don't need the corresponding map >> functions. Instead, we use open types and a registration and dispatch >> mechanism for values thus injected. > > Thanks for the hint. > > Do you have pointers to code examples using the "inject" function? It seems > to me that you will need to apply to it produce any "message" in the view > function. > > In our library, you can write directly: > > input "+" ~a:[value "+"; type_button; onclick `Plus] > > With the "inject" approach, do you need to write it like: > > input "+" ~a:[value "+"; type_button; onclick (inject `Plus)] > > ? Here's an example: https://github.com/janestreet/incr_dom/blob/master/example/incr_decr/counters.ml And the tradeoffs you imply is indeed there. I find the code without the type parameter easier to use and think about, but I agree that the "lightness" argument isn't 100% clear. Another advantage of the Event approach is that we have combinators like Event.Many that let you deliver a list of events together, and primitive events like Stop_propagation and Viewport_changed, which are always available, independent of the concrete event type. We've found this to be quite useful in separating out the pure and imperative parts of the application. > If so, this does not seem strictly lighter than using the "map" function > occasionally. Moreover this seems to open the door to possible problems if > a vdom fragment producing some kinds of messages is injected in a "host > application" that cannot process these messages. It also means that one > needs to take the identity of the "inject" function itself into account in > order to memoize vdom-generation functions. The issue about the identity of the inject function is real, and the use of Incremental helps us here, making it easy to preserve physical identity. Also, Incremental allows you to be freer in your use of functional programming idioms, letting you pass closures around to the various render functions without destroying physical equality. As far as I understand it, the Elm-style approach tends to require a fairly first-order style in order to make memoization effective. That said, using Incremental is a pretty heavy hammer to solve this problem, so if you don't care about incremental computation more generally, it's not clear it's worth the trouble. > Basically, we need "map" on "component boundaries", and even not always, > since components can take ad hoc injection functions to wrap their messages > into their "host" own message type (as the SelectionList example in > https://github.com/LexiFi/ocaml-vdom/blob/master/examples/vdom_ui.mli ). > > The library does use extensible types (with a registration/dispatch > mechanism) in two other places, though: > > - "Commands" (encapsulation of side-effectul operations). The set > of "command constructors" is small and has a global nature > (e.g. "AJAX query", "timer", etc), while the type of "messages" > is specific to each application and component. Nice. This is part of what we're doing in our Event type. > - "Custom nodes" in the VDOM which allow plugging "native" > components (again, the set of such possible components is more > "fixed" than messages). Interesting. I'll take a look. y ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-11-30 16:52 [Caml-list] Announce: ocaml-vdom (pre-release) Alain Frisch 2016-11-30 19:22 ` Yaron Minsky @ 2016-11-30 22:46 ` Martin DeMello 2016-12-01 9:56 ` Alain Frisch [not found] ` <CAG+nEjzO1qFfxHSMqueiKcTJyJYnREmvXhzGR7H+noBmV2oUKw@mail.gmail.com> 2 siblings, 1 reply; 12+ messages in thread From: Martin DeMello @ 2016-11-30 22:46 UTC (permalink / raw) To: Alain Frisch; +Cc: ocsigen, OCaml Mailing List [-- Attachment #1: Type: text/plain, Size: 1386 bytes --] Looks very exciting, thanks for the release! Any tips on setting up a project? For example, with elm I use elm-webpack-starter [https://github.com/moarwick/elm-webpack-starter], which sets up an asset pipeline and a dev environment with live reloading. martin On Wed, Nov 30, 2016 at 8:52 AM, Alain Frisch <alain.frisch@lexifi.com> wrote: > Dear all, > > You might be interested in the ocaml-vdom project which has been used by > LexiFi for some time and open-sourced recently. It contains two components > which we use to create our browser-side UIs with js_of_ocaml and which > might be useful to the community: > > - Bindings to the DOM and other browser APIs, implemented with > gen_js_api. (Partial bindings, expanded on demand.) > > - An implementation of a "virtual DOM" and the "Elm architecture", i.e. > a programming model where the UI is specified by a state type, a view > function (producing a functional version of the DOM), and an update > function that modifies the state based on messages (generated by UI events > or external interactions). > > > Project page: > > https://github.com/LexiFi/ocaml-vdom > > > -- Alain > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > [-- Attachment #2: Type: text/html, Size: 2309 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-11-30 22:46 ` Martin DeMello @ 2016-12-01 9:56 ` Alain Frisch 0 siblings, 0 replies; 12+ messages in thread From: Alain Frisch @ 2016-12-01 9:56 UTC (permalink / raw) To: Martin DeMello; +Cc: ocsigen, OCaml Mailing List On 30/11/2016 23:46, Martin DeMello wrote: > Any tips on setting up a project? For example, with elm I use > elm-webpack-starter [https://github.com/moarwick/elm-webpack-starter], > which sets up an asset pipeline and a dev environment with live reloading. I've added a simple "Usage" section to the project's README. But don't expect (yet) a rich ecosystem around the project! -- Alain ^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <CAG+nEjzO1qFfxHSMqueiKcTJyJYnREmvXhzGR7H+noBmV2oUKw@mail.gmail.com>]
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) [not found] ` <CAG+nEjzO1qFfxHSMqueiKcTJyJYnREmvXhzGR7H+noBmV2oUKw@mail.gmail.com> @ 2016-12-02 13:41 ` Alain Frisch 2016-12-02 16:59 ` Vincent Balat ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Alain Frisch @ 2016-12-02 13:41 UTC (permalink / raw) To: Vincent Balat, ocsigen, OCaml Mailing List Hi Vincent, First, let me insist that I have zero experience with functional reactive interface, Tyxml or React. So I'm not in a very good position to comment on them! My *intuition* is that the tradeoff would be a bit similar to the one with Jane Street's Incremental. Both FRP and SAC require to introduce extra concepts (signals, events, variables, observers; specific maps and binds) which add some weight compared to a simple one-directional "view" mapping from state to vdom. What you gain with those approaches is a more fine-grained notion of update, which can be necessary in some cases. Interestingly, Elm moved away from FRP : http://elm-lang.org/blog/farewell-to-frp . This is not just a shift of terminology, and it corresponds to the removal of the "Address" argument on the view function in favor of a parametrized vdom type: https://github.com/elm-lang/elm-platform/blob/master/upgrade-docs/0.17.md#no-more-signaladdress (In a sense, the "Address" argument is rather similar to the "inject" function which we discussed with Yaron.) About Tyxml itself: I think that it addresses a rather different set of issues (ensuring that the DOM is "statically correct" w.r.t. definition of HTML5/SVG). We haven't identified those issues as being relevant for us, i.e. we have never hit a bug related to breaking such validity constraints, and the lack of static typing does not seem to make refactoring UI code more difficult or fragile; so it's not clear to us that adding more static typing here would help. If we tried to combine it with our vdom approach, it would probably add some noise, since the vdom type would receive extra type parameters, which would be visible in the interface of all components exposing "view" functions. Alain On 02/12/2016 13:51, Vincent Balat wrote: > Hi Alain, > > How would you compare the virtual DOM with a functional reactive > interface, as you can do with Tyxml and React? > > -- Vincent > > Le mer. 30 nov. 2016 à 17:53, Alain Frisch <alain.frisch@lexifi.com > <mailto:alain.frisch@lexifi.com>> a écrit : > > Dear all, > > You might be interested in the ocaml-vdom project which has been used by > LexiFi for some time and open-sourced recently. It contains two > components which we use to create our browser-side UIs with js_of_ocaml > and which might be useful to the community: > > - Bindings to the DOM and other browser APIs, implemented with > gen_js_api. (Partial bindings, expanded on demand.) > > - An implementation of a "virtual DOM" and the "Elm architecture", > i.e. a programming model where the UI is specified by a state type, a > view function (producing a functional version of the DOM), and an update > function that modifies the state based on messages (generated by UI > events or external interactions). > > > Project page: > > https://github.com/LexiFi/ocaml-vdom > > > -- Alain > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-12-02 13:41 ` Alain Frisch @ 2016-12-02 16:59 ` Vincent Balat 2016-12-02 18:18 ` Alain Frisch 2016-12-02 22:31 ` Yaron Minsky [not found] ` <5db7c03d-bec8-8285-b458-82e681842dbb@zoho.com> 2 siblings, 1 reply; 12+ messages in thread From: Vincent Balat @ 2016-12-02 16:59 UTC (permalink / raw) To: Alain Frisch, Vincent Balat, ocsigen, OCaml Mailing List [-- Attachment #1: Type: text/plain, Size: 3647 bytes --] Using Tyxml with React is straightforward and makes your pages reactive almost for free. If your page contains : p [ text (string_of int i) ] you juste replace this by p [ R.text (React.S.map string_of int i) ] and it is automatically updated when the value of i changes ... And with Eliom you can even created these reactive pages from server side ... Vincent Le ven. 2 déc. 2016 à 14:42, Alain Frisch <alain.frisch@lexifi.com> a écrit : > Hi Vincent, > > First, let me insist that I have zero experience with functional > reactive interface, Tyxml or React. So I'm not in a very good position > to comment on them! > > My *intuition* is that the tradeoff would be a bit similar to the one > with Jane Street's Incremental. Both FRP and SAC require to introduce > extra concepts (signals, events, variables, observers; specific maps and > binds) which add some weight compared to a simple one-directional "view" > mapping from state to vdom. What you gain with those approaches is a > more fine-grained notion of update, which can be necessary in some cases. > > Interestingly, Elm moved away from FRP : > http://elm-lang.org/blog/farewell-to-frp . This is not just a shift of > terminology, and it corresponds to the removal of the "Address" argument > on the view function in favor of a parametrized vdom type: > > > > https://github.com/elm-lang/elm-platform/blob/master/upgrade-docs/0.17.md#no-more-signaladdress > > (In a sense, the "Address" argument is rather similar to the "inject" > function which we discussed with Yaron.) > > > About Tyxml itself: I think that it addresses a rather different set of > issues (ensuring that the DOM is "statically correct" w.r.t. definition > of HTML5/SVG). We haven't identified those issues as being relevant for > us, i.e. we have never hit a bug related to breaking such validity > constraints, and the lack of static typing does not seem to make > refactoring UI code more difficult or fragile; so it's not clear to us > that adding more static typing here would help. If we tried to combine > it with our vdom approach, it would probably add some noise, since the > vdom type would receive extra type parameters, which would be visible in > the interface of all components exposing "view" functions. > > > Alain > > > On 02/12/2016 13:51, Vincent Balat wrote: > > Hi Alain, > > > > How would you compare the virtual DOM with a functional reactive > > interface, as you can do with Tyxml and React? > > > > -- Vincent > > > > Le mer. 30 nov. 2016 à 17:53, Alain Frisch <alain.frisch@lexifi.com > > <mailto:alain.frisch@lexifi.com>> a écrit : > > > > Dear all, > > > > You might be interested in the ocaml-vdom project which has been > used by > > LexiFi for some time and open-sourced recently. It contains two > > components which we use to create our browser-side UIs with > js_of_ocaml > > and which might be useful to the community: > > > > - Bindings to the DOM and other browser APIs, implemented with > > gen_js_api. (Partial bindings, expanded on demand.) > > > > - An implementation of a "virtual DOM" and the "Elm > architecture", > > i.e. a programming model where the UI is specified by a state type, a > > view function (producing a functional version of the DOM), and an > update > > function that modifies the state based on messages (generated by UI > > events or external interactions). > > > > > > Project page: > > > > https://github.com/LexiFi/ocaml-vdom > > > > > > -- Alain > > > [-- Attachment #2: Type: text/html, Size: 6333 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-12-02 16:59 ` Vincent Balat @ 2016-12-02 18:18 ` Alain Frisch 0 siblings, 0 replies; 12+ messages in thread From: Alain Frisch @ 2016-12-02 18:18 UTC (permalink / raw) To: Vincent Balat, Vincent Balat, ocsigen, OCaml Mailing List On 02/12/2016 17:59, Vincent Balat wrote: > > Using Tyxml with React is straightforward and makes your pages reactive > almost for free. > > If your page contains : > p [ text (string_of int i) ] > you juste replace this by > p [ R.text (React.S.map string_of int i) ] > > and it is automatically updated when the value of i changes ... I'm not sure to follow: in the "Elm/vdom" approach, the original p [ text (string_of int i) ] has the behavior you describe: the content of the text node will always be equal to "string_of_int i" and you don't have to do any explicit update to achieve that. That's the beauty of the model. I guess this could be qualified as "reactive" as well, except that the entire view is refreshed when any part of the state change (and the vdom diffing approach makes this viable). -- Alain ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-12-02 13:41 ` Alain Frisch 2016-12-02 16:59 ` Vincent Balat @ 2016-12-02 22:31 ` Yaron Minsky 2016-12-10 13:34 ` SP [not found] ` <5db7c03d-bec8-8285-b458-82e681842dbb@zoho.com> 2 siblings, 1 reply; 12+ messages in thread From: Yaron Minsky @ 2016-12-02 22:31 UTC (permalink / raw) To: Alain Frisch; +Cc: Vincent Balat, ocsigen, OCaml Mailing List On Fri, Dec 2, 2016 at 8:41 AM, Alain Frisch <alain.frisch@lexifi.com> wrote: > Hi Vincent, > > First, let me insist that I have zero experience with functional reactive > interface, Tyxml or React. So I'm not in a very good position to comment on > them! > > My *intuition* is that the tradeoff would be a bit similar to the one with > Jane Street's Incremental. Both FRP and SAC require to introduce extra > concepts (signals, events, variables, observers; specific maps and binds) > which add some weight compared to a simple one-directional "view" mapping > from state to vdom. What you gain with those approaches is a more > fine-grained notion of update, which can be necessary in some cases. I think FRP and SAC are pretty different in their roles here. Really, SAC is just a system for optimizing a unidirectional computation --- in the end, your view is pretty close to a function of this signature: val view : Model.t Incr.t -> Vdom.t Incr.t which is really just an incremental version of an ordinary function. You don't have to think about anything signal-like when you consider the semantics of your function: the semantics are exaclty what you get if you replaced every monadic bind with an ordinary let-binding. My somewhat biased view is that SAC addresses performance, which is an issue of fundamental importance for UIs, whereas FRP doesn't address a problem which is similarly central. And the ability to express time-dependent computations (which FRP provides) adds lots of other problems (in particular, monadic FRP is plagued by space leaks.) > Interestingly, Elm moved away from FRP : > http://elm-lang.org/blog/farewell-to-frp . This is not just a shift of > terminology, and it corresponds to the removal of the "Address" argument on > the view function in favor of a parametrized vdom type: > > https://github.com/elm-lang/elm-platform/blob/master/upgrade-docs/0.17.md#no-more-signaladdress > > (In a sense, the "Address" argument is rather similar to the "inject" > function which we discussed with Yaron.) Having talked to Evan a decent amount about this, my takeaway is that FRP in Elm wasn't really used to improve performance, and without that, it wasn't worth the conceptual weight. Incremental adds some conceptual weight (less, I claim, than traditional FRP libraries), but it also solves a real problem. React and Elm style solutions are simply not capable of implementing highly efficient views of fast changing data; indeed, they typically use special-purpose imperative libraries for implementing applications that require it. Incremental lets you do this kind of optimization in one smooth, functional framework. The cost, obviously, is you need to be comfortable living in a monad. For our developers, this doesn't count as that much of a cost these days, given the proliferation of other monadic abstractions in our code. But it's not trivial. > About Tyxml itself: I think that it addresses a rather different set of > issues (ensuring that the DOM is "statically correct" w.r.t. definition of > HTML5/SVG). We haven't identified those issues as being relevant for us, > i.e. we have never hit a bug related to breaking such validity constraints, > and the lack of static typing does not seem to make refactoring UI code more > difficult or fragile; so it's not clear to us that adding more static typing > here would help. If we tried to combine it with our vdom approach, it would > probably add some noise, since the vdom type would receive extra type > parameters, which would be visible in the interface of all components > exposing "view" functions. We support both TyXML and a simpler, untyped vdom API. My personal view pretty much matches yours, but other users (Hugo Heuzard in particular) prefers it pretty strongly. The lack of an extra type parameter in our approach makes the integration with TyXML easier, I suppose. y > Alain > > > On 02/12/2016 13:51, Vincent Balat wrote: >> >> Hi Alain, >> >> How would you compare the virtual DOM with a functional reactive >> interface, as you can do with Tyxml and React? >> >> -- Vincent >> >> Le mer. 30 nov. 2016 à 17:53, Alain Frisch <alain.frisch@lexifi.com >> <mailto:alain.frisch@lexifi.com>> a écrit : >> >> >> Dear all, >> >> You might be interested in the ocaml-vdom project which has been used >> by >> LexiFi for some time and open-sourced recently. It contains two >> components which we use to create our browser-side UIs with >> js_of_ocaml >> and which might be useful to the community: >> >> - Bindings to the DOM and other browser APIs, implemented with >> gen_js_api. (Partial bindings, expanded on demand.) >> >> - An implementation of a "virtual DOM" and the "Elm architecture", >> i.e. a programming model where the UI is specified by a state type, a >> view function (producing a functional version of the DOM), and an >> update >> function that modifies the state based on messages (generated by UI >> events or external interactions). >> >> >> Project page: >> >> https://github.com/LexiFi/ocaml-vdom >> >> >> -- Alain >> > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) 2016-12-02 22:31 ` Yaron Minsky @ 2016-12-10 13:34 ` SP 0 siblings, 0 replies; 12+ messages in thread From: SP @ 2016-12-10 13:34 UTC (permalink / raw) To: Yaron Minsky; +Cc: Alain Frisch, Vincent Balat, ocsigen, OCaml Mailing List On Fri, Dec 02, 2016 at 05:31:00PM -0500, Yaron Minsky wrote: >I think FRP and SAC are pretty different in their roles here. Really, >SAC is just a system for optimizing a unidirectional computation --- > [..] >val view : Model.t Incr.t -> Vdom.t Incr.t > >which is really just an incremental version of an ordinary function. >You don't have to think about anything signal-like when you consider > [..] >My somehat biased view is that SAC addresses performance, [..] whereas >FRP doesn't address a problem which is similarly central. And the >ability to express >time-dependent computations (which FRP provides) adds lots of other >problems (in particular, monadic FRP is plagued by space leaks.) >[..] >Incremental adds some conceptual weight (less, I claim, than >traditional FRP libraries), but it also solves a real problem. Would be nice to read an article on these findings & comparison of the two concepts and their techniques. -- SP ^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <5db7c03d-bec8-8285-b458-82e681842dbb@zoho.com>]
* Re: [Caml-list] Announce: ocaml-vdom (pre-release) [not found] ` <5db7c03d-bec8-8285-b458-82e681842dbb@zoho.com> @ 2016-12-05 15:55 ` Ashish Agarwal 0 siblings, 0 replies; 12+ messages in thread From: Ashish Agarwal @ 2016-12-05 15:55 UTC (permalink / raw) To: Drup; +Cc: Alain Frisch, Vincent Balat, ocsigen, OCaml Mailing List [-- Attachment #1: Type: text/plain, Size: 2223 bytes --] I don't have a strong opinion either way, but one point not mentioned about Tyxml is that you get nice auto-completion when combined with merlin. I've been pleased to learn the possible values for some attributes while coding without having to reference any documentation. On Sat, Dec 3, 2016 at 10:27 AM, Drup <drupyog@zoho.com> wrote: > > About Tyxml itself: I think that it addresses a rather different set of >> issues (ensuring that the DOM is "statically correct" w.r.t. definition of >> HTML5/SVG). We haven't identified those issues as being relevant for us, >> i.e. we have never hit a bug related to breaking such validity constraints, >> and the lack of static typing does not seem to make refactoring UI code >> more difficult or fragile; so it's not clear to us that adding more static >> typing here would help. If we tried to combine it with our vdom approach, >> it would probably add some noise, since the vdom type would receive extra >> type parameters, which would be visible in the interface of all components >> exposing "view" functions. >> > > Tyxml is not only about type-safety. It's about providing an exhaustive, > consistent and convenient HTML5 API for your users. > > Tyxml also gives you combinators covering the complete HTML5 surface API. > This API will be exactly the same as the various other implementation of > Tyxml (textual (Tyxml.Html), dom/react (Tyxml_js), incremental (JST's > library), react/shared (in eliom)). > Any user that is familiar with one of those API will be able to pick up > the others extremely easily. > > Currently, in your API, you implemented 3 elements: div, input, span. > You'll have to build all of the others by hand. You don't even have > attributes, only the underlying primitives. Tyxml provides a nice API with > sum types and correct types for all HTML5 attributes. > > Finally, you get a syntax extension that takes the usual HTML syntax and > generates the appropriate combinator calls. You don't have to use it, but > some users want to. :) > > Of course, there is a price to pay, you need to implement Tyxml's > Xml_sigs.T. I believe it's not a high price, although your extra type > parameter makes this kind of things more delicate... > > [-- Attachment #2: Type: text/html, Size: 2714 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-12-10 13:34 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-11-30 16:52 [Caml-list] Announce: ocaml-vdom (pre-release) Alain Frisch 2016-11-30 19:22 ` Yaron Minsky 2016-12-01 9:32 ` Alain Frisch 2016-12-01 22:18 ` Yaron Minsky 2016-11-30 22:46 ` Martin DeMello 2016-12-01 9:56 ` Alain Frisch [not found] ` <CAG+nEjzO1qFfxHSMqueiKcTJyJYnREmvXhzGR7H+noBmV2oUKw@mail.gmail.com> 2016-12-02 13:41 ` Alain Frisch 2016-12-02 16:59 ` Vincent Balat 2016-12-02 18:18 ` Alain Frisch 2016-12-02 22:31 ` Yaron Minsky 2016-12-10 13:34 ` SP [not found] ` <5db7c03d-bec8-8285-b458-82e681842dbb@zoho.com> 2016-12-05 15:55 ` Ashish Agarwal
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox