I’m pretty sure you are right. It seems to me that both FRP and ECS models of UI are at least as good as OO models, and a lot more adaptable to Rust than conventional OO models. But GUIs and OOP grew up together and have been deeply wedded, so non-OO UI just isn’t how people are used to thinking, for the most part.
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.
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.
Also - as you hint it's entirely unnecessary, I do actually believe OO is a natural match for UI because of the overlap between components.
I think it's the fact in UI you have a big chunk of state, with references all over, and sometimes doing sort of 'circular references' ... Rust code starts to have a lot of the various Vec Rc Cell Box all over the place, and then honestly 'what's the point of rust'?
And doing 'observers and events' feels unnatural, as well as the rest of the threading/stateful issues related to GUI.
UI is also about a lot of small details and so the typing->compile->quick check is something that happens possibly more in UI - you have to often 'see' the results you can't just run the test.
I like Rust, but it is a bit of 'Chinese Finger Trap' for smart people, and applying it to UI I think is basically upside down. I mean - fun to reason about and experiment with - but basically just wrong.
I wonder if someone will come up with a language that is the UI version of Rust, with sufficient checking etc.. That would be cool, though I can't even fathom what that might be.
Well, C and C++ also has all of these, with the former having it in a convention-only manner, where you have to learn what the author intended for every project. These are generic paradigms that are useful and often needed for low-level programs, and Rust makes their usage safe.
What I do find problematic regarding rust is that people want to apply it to everything, when it is a low level language, no matter how convenient it can look on the surface. Managed languages are more than fine for the vast majority of problems, they should not be replaced.
One of the reasons why is that the notion of a GUI is ill-specified. Most ui frameworks, including the excellent ones, like QT, have corner cases where they fail. It's just that we've gotten to the point where coders kind have it in their bag of tricks to avoid these situations by defensive programming.
Until we have a proper model of graphical UI, it'll be hard to make any such language.
Think about the last time you had a weird UI bug (screen not redrawing, unexpected behavior, not able to see something that should be in scroll view, not able to scroll to something that is out of bounds, etc). Now think of the last time this happened in a terminal or REPL.
We have no model of user interface that adequately covers the corner cases. We do have a model for CLIs. That's why guis tend not to work.
Honesty though I fear in attempt to 'find' a model, we get forced upon us this FRP stuff for academic reasons of architectural purity. Despite QT's bugs, it mostly works just fine.
Many CLI programs were designed in the assumption the display size never changes, like 80x25 characters. That's not true anymore, users resize their windows, the text in the terminal may or may not stay good after that.
Terminals have a GUI state: cursor position, and current text attributes. That state may cause issues, especially when a program quits suddenly, like a crash.
I have never in my life witness a terminal crash so hard that I couldn't fix it and get back all my other state. In 100% of cases, just typing Ctrl+C, Ctrl+Z, etc, followed by 'r', 'e', 's', 'e', 't', enter seems to have always done the trick.
Can confirm, these things helped me as well.
Still, just because there's an easy workaround doesn't cancel the fact the observed behavior is a weird UI bug.
Otherwise, one could argue web apps don't have weird bugs because there's F5=Refresh key which fixes 99% of them.
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.