4 ms·
The thing is, there do exist UI frameworks that prefer composition over inheritance and strictly tree shaped components where data only flows one way: they're a
by jchw 4y ago
The thing is, there do exist UI frameworks that prefer composition over inheritance and strictly tree shaped components where data only flows one way: they're all the rage on the web.
And that's great, because they give plenty of useful insight into things that work and don't work when designing UI frameworks this way.
To be fair, it's not exactly like nobody realized this. More than one Rust desktop UI framework is explicitly React inspired, and it's not like FRP-based UI was non-existent prior to being popularized in web frameworks. Still, all the same... I suspect the best answers for how to do good UI in Rust are not far away from this paradigm.
- jollybean 4y agoSo the question is, why are we wrangling our UI approach to match the strict nature of software languages? Isn't that kind of upside down? Wouldn't the obvious lack of fit hint at perhaps some kind of fundamental impedance mismatch? While most other techs are not a perfect fit, Rust is a 'worse fit' for the kinds of things we want to do in UI. The 'design objectives' of UI for the most part just do not apply at all. Even the 'Stateless / Unidirectional' tree patterns seem to be a bit inverted as I think the slight advantage of thinking just a bit about hierarchy in a different way is abnegated by the hurdles imposed when it does happen. Dart is a good language for UI, I suggest better than Rust in almost every way. The 'advantages' of Rust may present themselves in at lower layers. And both the unidirectional and even 'stateless' (i.e. Flutter) are mostly unnecessary. We'd be better served by some fairly basic conventions. I will admit I 'learned' something by using the fairly strict hierarchy in Flutter - and am better for it - but I still want my 'statefulness' tree back.
- galangalalgol 4y agoI'm pretty sure the mismatch is just that the major ui frameworks were designed for oop languages, not that UI is inherently oo. As the gp said, react type frameworks play fine with languages that have no inheritance. It's just a matter of a few more coming along with the same paradigm(s).
- sudosysgen 4y agoIt's really not inheritance that's the issue. The issue is that in Rust it's difficult to have a data flow between objects that goes in multiple opposing direction, ie, a graph instead of a directed tree. Inheritance is a way of doing that, but not the only one. Rust is capable of every OOP design pattern except ones that require this kind of dataflow inversion which become cumbersome.
- deleted 4y ago[deleted]
- verdagon 4y agoI suspect the mismatch is actually due to the borrow checker's inability to do various common abstractions such as delegates and observers. These patterns are quite useful, especially in stateful situations such as GUI. They help decouple observer from observable, and can give an architecture more flexibility in a lot of ways. Alas, the borrow checker isn't very amenable to that sort of style.
- iovrthoughtthis 4y agoyup. we need to find a way to manage multiple owned borrows safely
- tene 4y agoWe already have a way, reference counting and locking, the same way it's handled in most dynlangs.
- jollybean 4y agoThe borrow checkers inability to do those abstractions is evidence of the greater ontological mismatch ... which is my point. UI's are 'inherently' trees, data that needs to be mutated, at least some degree of self and circular referencing. All of that a bit outside of Rust scope. More pragmatically, UI code tends to be 'wide and flat' - i.e. a ton of 'little things' and screens, mostly independent from one another, with visual elements. You really want to be able to code fast, compile fast, 'try things' for validation. Performance is usually not a primary concern. That's contrary to Rust ethos where they trade all of that away for performance. So, it's a bit upside down in my view. Rust UIs I can see for automotive, critical systems etc. - but even then - I suggest the UI should be disassociated from the 'critical' part.
- nyanpasu64 4y agoI don't like React: https://news.ycombinator.com/item?id=31981947 https://news.ycombinator.com/item?id=31981947 > In Cocoa, scroll position is part of the view's state, a mere property of the view. This is simple because the UI itself is stateful. > In React, scroll position is typically not part of the state from which we project the view. Instead this state is attached to the projection itself (e.g. a HTML node) and we are dependent on the "Memoization Map" to preserve it. So this memoization is now required for the correct functioning of the app. The "pure function" abstraction is leaking.
- kristiandupont 4y agoI struggle to understand what you are saying here. What do you mean when you say "this memoization is now required for the correct functioning of the app"? I agree that there can be some issues with scroll restoration in routing, but it doesn't seem like a big issue to me and certainly doesn't seem to reveal some fundamentally flawed architecture.
- nyanpasu64 4y agoHaven't written React, but it relies on memoization to preserve hidden state (like text carets and item scrolling) not tracked by your application. If you change the tree structure of your GUI (add/remove/move elements), and don't give scrollable UI items a key if they move, React will delete the scrollable DOM element and create a new one scrolled to the top, losing the user's scroll progress. The same goes for text fields with horizontal (or vertical) scrolling and active cursor position, perhaps text field contents (unsure), etc.
- kristiandupont 4y agoAgain, I am not sure if I am just misunderstanding something but that doesn't sound right to me. >it relies on memoization to preserve hidden state It relies on the DOM to keep that state. It's not hidden, you are just not forced to deal with it or think about it. >If you change the tree structure [...] and don't give scrollable UI items a key if they move, React will delete the scrollable DOM element [...] Yes, if you have an array of elements, you need to give them a unique identifier. This is a fundamental property of any diff-algorithm which the virtual DOM relies on. I don't think that is unreasonable, and IMO it is not something that adds significant cognitive load. React definitely has quirks and especially optimizing for performance can be quite complex. But out of all the GUI frameworks I have tried (including Win32, WinForms and GTK as well as other web ones), React is the most intuitive to me.
- kaba0 4y agoThe DOM still propagates events upwards, resulting in backwards tree-traversal.
- jchw 4y agoIn theory, though, with React it is idiomatic to make the state flow back through a state store like Redux, then those state changes are reflected in the top-down re-rendering. That's not a problem for Rust, as evidenced by the fact that it is actually the way several frameworks work in Rust today.