26 ms·
Moxie: Incremental Declarative UI in Rust
- anp 7y agoAuthor here. I'm trying out an optional email Q&A format on the post, but will also be keeping an eye out here.
- sansnomme 7y agoWebsite on mobile needs a bit of fixing. Also, what do you think of Svelte?
- anp 7y agoscreenshot? how does reader mode look on your phone?
- anp 7y agoI think there are some very strong parallels between the approach Svelte has taken and what I'm trying out in moxie-dom: https://twitter.com/anplolol/status/1121128610918567936?s=20 https://twitter.com/anplolol/status/1121128610918567936?s=20
- gyrgtyn 7y agohow well does your editor deal with the quasi xml?
- anp 7y agoFairly well, although I need to manually format it. VSCode's syntax highlight for rust doesn't do anything fancy for tags and attributes, but literals and block expressions are highlighted correctly.
- Devagamster 7y agoNot a question so much as encouragement. I think a big unspoken benefit behind react and its ilk is the strong focus on concise readability. React hooks can be confusing to understand, but when used properly they are incredibly concise and readable. I think moxie is closest to doing this properly in rust, and as such I am watching it very closely. Awesome stuff.
- pgt 7y agoAny discussion about incremental UI should include Yaron Minsky's talk about Jane Street's OCaml framework, incr_dom from 2016: https://www.youtube.com/watch?v=R3xX37RGJKE https://www.youtube.com/watch?v=R3xX37RGJKE Incremental is essentially an implementation of Adapton from 2014: https://www.cs.umd.edu/~hammer/adapton/ https://www.cs.umd.edu/~hammer/adapton/ There is a big upset coming in the UX world as we converge toward a generalized implementation of the "diff & patch" pattern which underlies Git, React, compiler optimization, scene rendering, and query optimization. Two sleeper startups in this space that are going to make a lot of money are Frank McSherry's Materialize Inc. and Nathan Marz's Red Planet Labs. incr_dom source: https://github.com/janestreet/incr_dom https://github.com/janestreet/incr_dom Differential Dataflow: https://github.com/TimelyDataflow/differential-dataflow https://github.com/TimelyDataflow/differential-dataflow Declarative Dataflow Client: https://github.com/sixthnormal/clj-3df https://github.com/sixthnormal/clj-3df Crux adapter for Declarative Dataflow: https://github.com/sixthnormal/clj-3df https://github.com/sixthnormal/clj-3df
- anp 7y agoHeartily agreed re: Materialize, and I've also been nerd-sniped by Adapton, although less literally than incr_dom.
- pgt 7y agoWhatever you do, do not read the META II paper, especially not Figure 5, which is the META II compiler written in itself. You may lose two months of your life: http://www.ibm-1401.info/Meta-II-schorre.pdf http://www.ibm-1401.info/Meta-II-schorre.pdf :)
- amelius 7y ago> Two sleeper startups in this space that are going to make a lot of money ... How are they going to make money if open source enthusiasts copy the ideas and spread them for free? See e.g. React -> Vue. Selling developer tools these days is just a losing game.
- pgt 7y ago
- ryuukk_ 7y agothe syntax, it is HORRIBLE they'll go nowhere with that
- anp 7y agoI'm not happy with the state of the syntax, but I'm pretty sure it'll take me farther than this attitude.
- derision 7y agoNot sure if it's because of rust (not super familiar with the language) but the syntax seems really awful
- deleted 7y ago[deleted]
- nerdponx 7y agoI'm not a Rust user either. It's a lot of "symbol noise" to me, but I assume this is the kind of thing you get used to reading after a while. However it looks very annoying to type all those symbols, even if you have some kind of customized ergo keyboard.
- anp 7y ago> some kind of customized ergo keyboard I use an ErgoDox, and while my layout isn't customized for writing mox invocations, it hadn't occurred to me that this might be a blind spot in my thinking about ergonomics. Good point!
- WhatIsDukkha 7y agoI didn't really see anything that was weird whatsoever from a normal day to day programmer (Rust or not) perspective so I wouldn't take his feedback to heart or worry about your ergodox.
- nerdponx 7y agoIt seemed like a high ratio of "non-alphanumeric symbols" compared to a lot of other code that I read and write.
- WhatIsDukkha 7y agoI suspect you are keying on some of the Rust language bits in the middle of his syntax. _ is "don't complain because I don't use this variable" || is the syntax around Rust closures foo! is a Rust macro Why this is desirable is that we can program in real Rust while using some simple macro expansion not to create a free standing language for gui building? Learning Rust via this gui library might not be the best choice(?) and I think it's better he focus on people that know Rust already.
- mkettn 7y agoWhats the advantage over just writing vanilla html5? Regarding your mental model: This looks quite similar to IEC 61499
- anp 7y agoAh, that's a good reference for a more modern "control loop" idea. I agree that there are many similarities with that specification and I need to read in more depth. Thanks! Honestly, there's limited advantage over vanilla HTML5 if HTML is actually what you were going to write. The website at moxie.rs is plain HTML/CSS/etc. The reason to reach for tools like this on the web is if you want interactive state, complex data transformations, etc. I think it will be hard for moxie-dom to compete directly on ergonomics with purely web-focused tools (especially JS frameworks), because the underlying tools will always need to maintain some distance from platform semantics.
- kelnos 7y agoI think if you want vanilla html5, you probably have a simple static site, or something with minimal (or server-side-only) dynamic components. If you want to build a highly-dynamic SPA, vanilla html5 will become an accidental exercise in reinventing a web framework, but poorly.
- for_the_many 7y agoIt's nice to see that the traditional desktop GUI programmers finally realize that the way the Web people do GUIs is right (React/Vue/...) and the way they did it until now (QT/GTK/WPF/...) is wrong. Many think that the only reason people use Electron is that it's cross-platform, when that is actually a minor benefit. The big one is just how much more better and efficient React/Vue/... are at creating GUIs. I say that as someone who programmed GUIs in pretty much everything, starting with MFC.
- anp 7y ago> traditional desktop GUI programmers finally realize FWIW, I'm not a desktop GUI programmer nor am I an...uh...professional GUI programmer of any kind. Not sure exactly who is doing the realizing here, but if they are, then great!? > the way the Web people do GUIs is right There are definitely some attractive things about web frameworks' approaches, but it's important to remember that the history of "declarative UI" traces a path back through C++ imgui devtools before React happened. I see the transition here differently -- the web is so opinionated about the DOM and its rendering engine, the only thing you can iterate on to make yourself more productive is the frontmost application semantics. Full-pipeline UI toolkits have to manage changes across all the various phases of their implementations. This (I think) creates an environment where the web is a great incubator for application model experimentation. However, many projects that start on the web have a difficult time faithfully mapping to the semantics of other GUI systems (one of the driving forces behind Electron adoption IMO). This gap is one that moxie hopes to bridge -- ideally we should be able to learn from the highly productive web ecosystem while transferring those learnings further into the UI stack without the overhead and performance cliffs of typical web tools.
- layoutIfNeeded 7y ago> The big one is just how much more better and efficient React/Vue/... are at creating GUIs Efficiency is not the first thing that pops to my mind when I look at the Electron-based apps in my task manager.
- Tronno 7y agoThey were probably referring to speed/ease of development, not application performance.
- bluejekyll 7y ago> the goal is to write the code "generically with respect to time," describing the state of the UI right now for any value of now. I think this is clearer in the above code samples, where the code always executes a complete declaration of the desired UI rather than explicitly mutating prior state. I almost wish the post led with this, anp. It’s such a great and concise description of the aim for the project, and really helps clarify all underlying decisions. Thanks for writing this post. It’s great!
- anp 7y agoGreat idea on the intro. Moved some things around, should be online soon. Thanks for the kind words <3
- kibwen 7y agoFor more in the Rust UI space, see also Iced, which has an Elm-inspired reactive model: https://github.com/hecrj/iced https://github.com/hecrj/iced
- epage 7y agoAlso Relm which is Rust+Elm-inspired+Gtk https://github.com/antoyo/relm https://github.com/antoyo/relm
- mdtusz 7y agoAlso yew. It's more web focussed, but it works great running in a WebView for a local application with RPC to a background server running locally. https://github.com/yewstack/yew https://github.com/yewstack/yew
- tracker1 7y agoAlso Yew[1], which is a bit different, but a relatively flushed out component model. [1] https://github.com/yewstack/yew https://github.com/yewstack/yew
- adev_ 7y agoI like the ELM model for UI. The stateless/functional view approach is very similar to IMGUI [^1]. It makes things much less error prone with much less state management / hierarchy management to do than the React model. [^1]: https://github.com/ocornut/imgui https://github.com/ocornut/imgui
- dakom 7y agoSo... semi-serious question, what does html/css give us that imgui doesn't? e.g. taking this idea in another direction - why not just replace the dom hierarchy with a single webgl node and compile imgui to wasm in order to drive it that way?
- for_the_many 7y agoText rendering is extremely difficult. Even today, Chrome/Firefox are not fully hardware accelerated on this front. https://gankra.github.io/blah/text-hates-you/ https://gankra.github.io/blah/text-hates-you/
- dakom 7y agoGood point and thanks for the link! However, doesn't it imply that text rendering is a bottleneck anywhere - games, digital signage, etc.? No doubt there's good reasons for the slow browser performance (like text as you mentioned, layout, event management, etc.) ... but it's still kinda crazy that with the power of computers today, tearing down and building up a tree that results in calculations for no more than a few thousand sprites or so is a performance killer. Would be nice if I could just re-render the entire DOM every tick. I've been playing with doing exactly that via lit-html and it seems to be working fine... but still, the idea is "the dom is sensitive - don't change what you don't need to" :\
- raphlinus 7y agoThis is complicated, but the short answer is that it motivates actual incremental approaches, as opposed to rebuilding the world from scratch all the time. Imgui works best when the rendering is fast, which can be the case when the GPU is doing almost all of the work.
- dakom 7y agoOh, I see - although this is a relatively old issue on the imgui repo, seems like it's the bottom line (and expresses the same ideas mentioned here): https://github.com/ocornut/imgui/issues/1228#issuecomment-315516511 https://github.com/ocornut/imgui/issues/1228#issuecomment-31...
- guelo 7y agoOne of the issues with React-style "declarative" UI frameworks is that they have a hard time modeling transitions and animations. I'm not a Rustacean but that would be one of the things I'd look for here.
- anp 7y agoAgreed! I have some thoughts about how this can be handled but it’ll be a little bit before we can try them out.
- hellofunk 7y agoIf you take the animation out of the DOM-level code and put it in the CSS, doesn't that fix the issue? React then does not need to know about or control the animation and the browser just does what it does natively as things get added or removed from the DOM.
- WAHa_06x36 7y agoThat leaves you with very simple and bland animations, and very little flexibility.
- hellofunk 7y agoHm, have you seen some of the incredible and fine-tuned animations possible with all the CSS features for that? I think it's pretty amazing and relatively easy.
- edflsafoiewq 7y agoThis also requires that we have someone else who does animations for us, rather than doing all the UI ourselves.
- dsego 7y agoCSS animations are not enough for anything but simple transitions, since they are time based. Their behavior is also hard to control from JS. Check out this react animation library, which is based on springs for natural motion: react-spring.io (intro youtu.be/1tavDv5hXpo).
- akavi 7y agoIs it safe to call this "React.js for Rust?", or is there a nuance I'm missing? (Don't intend that to be dismissive; I'm a huge react fan)
- anp 7y agoFrom far down in the post: > I have described moxie a few times as "what if a React in Rust but built out of context and hooks?"
- 3fe9a03ccd14ca5 7y agoCan this be easily built as a static binary? I mean, really static, as in pop it onto your mother's windows laptop and let her double-click it and run the program?
- anp 7y agoDon't see why not, although to do so you'd need to use moxie-native which is still very new.
- r-w 7y ago> Each time the button is clicked, the closure in boot runs in entirety but if you open your browser's devtools on the iframe, you should see that only the necessary DOM nodes are seeing updates: Isn't that still radically inefficient?
- Devagamster 7y agoNot really. The assumption is that modifying the dom directly is the expensive part.
- erikpukinskis 7y agoDoesn’t seem like a good bet for the long term. There’s no practical reason why modifying the DOM couldn’t be practically free. Especially if we can hint to the layout engine that we’re working in a well behaved subset. (Or the layout engine can detect such)
- aassddffasdf 7y agoRight. All this treating the DOM with kid gloves seems to be due to its pre-existing weaknesses. Why not just fix those?
- opencl 7y agoBrowser vendors have spent the past several decades trying to fix those weaknesses and haven't, it seems like a very strong indication that it is not exactly an easy thing to do.
- fulafel 7y agoThis might be just because most web apps never had a bottleneck on JS->DOM changes.
- RussianCow 7y ago
- pier25 7y agoAnyone else plays "Surviving Mars"? https://survivingmars.gamepedia.com/MOXIE https://survivingmars.gamepedia.com/MOXIE
- TeMPOraL 7y agoNo, but I thought about it. Is the game any good?
- pier25 7y agoIt's pretty casual but I love it.
- DataGata 7y agoThe game is good once you get the hang of it, but there are bursts of micromanaging followed by long droughts of waiting for shit to happen. At max speed, the game will do 1 day/3 minutes. Most of the Steam achievements take about 60-100 days to do, which means 3-5 hours per game with lots of time spent not interacting much. Of course, to get to a "full fledged" colony it can take as many as 10 hours of gameplay, which again is mostly waiting for your commands to happen. Also, because its a Paradox game, the interface is ass. If you like the genre of games, this is one to lose a couple of dozen hours to. If you just think "oh, Mars is cool" its probably good to skip or download a mod that lets you zoom time faster.
- TeMPOraL 7y ago> Also, because its a Paradox game, the interface is ass. Huh, it's a Paradox game? Thar alone makes me interested; I'm a big fan of Stellaris. > bursts of micromanaging followed by long droughts of waiting for shit to happen Yeah, that sounds like Stellaris. Thanks for the review; I'll check the game out.
- pier25 7y ago> Huh, it's a Paradox game? It's published by Paradox not developed by them.
- erikpukinskis 7y agoA lot of innovative frameworks take the approach of forcing everything through a single paradigm, so that you can avoid solving a whole class of problems. It seems like a good trade off—yes, everything must be done just so, and perhaps some parts of your app are a little awkward, or a little boilerplate-y, but there’s a whole giant class of problems you can just totally ignore. Until... you can’t. There’s another approach to library authorship, where the goal is not to delete a class of problems, but to make a class of problems easily controllable. Not to make a large domain disappear, but to make it programmable. I have found, with that as your goal, you will be pushed away from declarative models. Because declarative models are about making a surface which is not programmable but configurable. You can’t program arbitrary relationships across a React component boundary. You must flatten your intent into the very tight declarative interface which exists there. Procedural models allow you to use the full set of capabilities that a function call and type system gives you. Ideally you don’t use much of that capability at any one time. But the beauty is you can use exactly the right control structure for the specific concern you are trying to... not abstract away, but make controllable. The set of “concerns” is the infinite set. And no possible declarative model can capture it. Functions can.
- anp 7y ago> And no possible declarative model can capture it. Functions can. If functions are your declarative model, what would you say?
- erikpukinskis 7y agoWell, in most apps you will layer both kinds of models. You’ll have SQL which is declarative, but you’ll call those queries as procedures. The boundaries around a React component are declarative, but the render function is procedural. So when I talk about declarative models I’m talking about the Swiss cheese of declarative models with procedures mixed in.
- anp 7y agoIn moxie, everything is procedural, as it were. The declarative syntax is a way to invoke "imperative but idempotent" functions, and the core runtime provides tools for wrangling mutability and repetition in those functions.
- giancarlostoro 7y agoThis looks great, was kinda disappointed they didnt have a DOM demo for the calculator, woulda really sold it even more honestly. It looks great otherwise. I wish Go had more efforts like these, Fyne is as nicely a UI as I could find for Go thus far. I think every modern language should really produce a UI library as part of the STD lib even if it's rather basic.
- anp 7y agoGood idea to make a DOM example for the calculator! I'm very behind on examples. Someone recently got very close to having the moxie-native calculator working in a browser's wasm/webgl, which will be mindblowing if they get it to work.
- giancarlostoro 7y agoI think even for documentation it would sell it amazingly well if you can see sample GUI code and run it in the browser and try out the result, even if it's not interactive editing wise.
- mywittyname 7y agoI'm not clear on something: is this translated into javascript or does this provide an HTML render with native Rust hooks?
- anp 7y agomoxie-dom is compiled to WebAssembly, and mutates the DOM using APIs from javascript. The Rust isn’t translated into JS, but it does run alongside it. moxie-native doesn’t have anything to do with JS or HTML, aside from reusing some concepts from CSS.
- toastal 7y agoIf you have a chance to start fresh on building a UI DSL, why would you choose XML?
- anp 7y agoFamiliarity. In short order it’ll be easy enough to write moxie functions without the xml macro, at which point it becomes a matter of preference.
- ducaale 7y agobrisk-reconciler[0] is in the same vein but implemented in ocaml/reasonml. Its currently used by brisk[1] and revery[2]. [0] https://github.com/briskml/brisk-reconciler https://github.com/briskml/brisk-reconciler [1] https://github.com/briskml/brisk https://github.com/briskml/brisk [2] https://github.com/revery-ui/revery https://github.com/revery-ui/revery
- danr_ 7y ago> moxie assumes that the program will enter from the "top" of the tree each time. [...] My suspicion is that Rust may be fast enough along with the right memoization strategies to never worry about the time spent getting from the root of the tree to nodes with changes. I think there is reason to worry: consider a node with a lot of children, for example a list of many todos. Say you want to change the state of one single todo, for example marking it as done. With a top-down approach such as diffing you have to go through each child to see if it has changed. This is O(n). If you instead have components that know their position in the tree and can react to external changes, like react's Components or using hooks and useState, this can be updated in O(1).