At the end the result is good, but the code looks awful.
At the end the result is good, but the code looks awful.
That being said it's been a while since I've used gtk-rs so it is entirely possible things have changed. I'd love to be corrected if that's the case :)
This is such a pain that even Gtk-rs samples have macros to work around cloning widget state into callbacks.
From my point of view language ergonomics still need to improve for Rust to actually be a candidate for GUI development, versus what the GC based languages (RC and tracing GC) offer out of the box with their UI kits.
Unless one envisions it just to take C++'s role of visualization layer and integration with graphics drivers.
Ownership defines who frees who. Parentage defines control nesting. References should to be handled via an indirection (e.g. names) and a protocol so that referees get notified when referents die. The indirection means that components get wired up in a late bound fashion; and the late binding means the gubbins for a protocol can be in place by then.
This stuff was figured out reasonably well with Delphi's VCL.
Even simple stuff like what Apple has demoed with SwiftUI designer can be a challenge, as you cannot just drag stuff around without changing the ownership semantics.
Naturally Swift has the advantage that Rc<RefCell<T>> is implicit, so it isn't as if the cost is magical gone.
However having to deal with it explicitly is a hard sell for anyone used to the comfort of GUI tooling.
So I imagine Rust is an easier sell for doing the low level stuff of a GUI engine, with what 90% of the devs using some managed language on top.
Basically what is happening to C++ on current desktop and mobile OSes, although for different reasons.
Or what is being done to Firefox actually.
Since then it got better libraries which reduce lots of the verbosity (e.g. gtk-rs), which is great. But the language itself probably won't change too much to better accommodate that use-case, since what things things painful here are the core features that prevent issues elsewhere.
I think we have to accept the fact that for different kinds of problems different programing languages are preferable instead of trying to find a single solution for all problems.
For UIs I think a naturally garbage-collected or refcounted language with reasonable support for dynamic dispatch is a lot easier to work with. In addition to that a restriction towards a single thread or even an inbuilt event loop can avoid bugs, improve interoperability between libraries, and reduce the amount of boilerplate and application-level design decisions even further.
If we take those properties we get the most common languages for GUI apps: Javascript/Dart which have single-threaded runtimes, and C#/Java/Kotlin/Swift as general-purpose languages which are more powerful but require an eventloop on application/library/framework level.
Those properties actually also expand to other very stateful and very concurrent applications. E.g. stateful network servers (something like Redis or a websocket server) have similar implementation challenges, and therefore are currently not very straightforward to write in Rust either (compared to e.g. in node.js).
This seems to work OK in SWT, so what's the problem in GTK/Rust? Are there some particular categories of objects that don't fit into that hierarchical model and need to be handled with a GC?
(Those objects would presumably be regular Java objects in an SWT app and handled by Java's GC.)
[1] https://www.eclipse.org/articles/swt-design-2/swt-design-2.h...
"Appendix: What the proposal won’t fix"
http://smallcultfollowing.com/babysteps/blog/2017/07/11/non-...
So one could say, it is a case of holding it wrong, and a Rust UI toolkit needs to be written from scratch. Which might be ok, but it does require some support for market adoption.
Having said this, Gtk-rs now has some help in the form of relm, exactly to overcome this issue.
I'm not really sure this can be reconciled with any arbitrary C library. One of the benefits I see from Rust is the ability to be unable to do unsafe things without explicitly stating you know what you're doing, thus preventing various classes of errors. But it feels like if the ownership model just doesn't fit with Rust's model that allows those guarantees to be made in the first place, it won't work. You can't write just anything in safe Rust without limiting the things you can do, but C libraries don't have such limits.
It might take creating new ways of representing GUI objects before the best model for that problem arises for Rust. I don't think libraries like GTK were designed with the lessons in safe memory management Rust learned from years after the fact in mind.
[0] http://way-cooler.org/blog/2019/04/29/rewriting-way-cooler-i...
It also might be that Rust is not the right language to write high level UI logic in at this time, and a GC'd language would be more appropriate. That's fine too. One of the strengths of Rust is its interoperability with other languages. C and C++ are certainly not the right languages to implement high level UI logic in, for example.
Let me be clear: Given the choice between Rust or C++ for writing Photoshop, I will pick Rust every time.
Apparently because that is the only way to sell MFC/ATL holdouts to WinUI, and allow WinUI to be called from classical Win32 without too much overhead, and also because .NET Native ideas will be migrated to .NET 5.
C++'s problem is that the path of righteousness is too narrow, but with heavy cultural idioms and norms, you can keep a lot of the people safely hemmed in, while retaining all the escape hatches.
Empirically, no, you cannot. Nobody has succeeded at writing memory-safe C++ at scale using normal software development practices.