Live data from Hacker News

Advice for the next dozen Rust GUIs

raphlinus.github.io

221–230 of 279 posts

Re: Advice for the next dozen Rust GUIs

#221
post #172

Earlier quoted context omitted.

yes there’s absolutely no need for UI to be multi-threaded. You can do stuff in the background but IMO multi-threaded UI is completely useless. You have an event loop where you poll for input => propagate changes => commit changes => rerender UI. Normally you might have poll => propagate => rerender, but when you delay the changes you can represent everything in a shared reference, and when commit them you have a sin…

Not really UI, but wasn’t one recentish game really performant due to it using Vulkan, but in a multi-threaded way? Not sure whether it would benefit traditional UIs though.

Intensive graphics rendering is something which does deserve the GPU and multiple cores. But most "UI" as we see it shouldn't be that intensive. UI drawing is usually on the GPU but stuff like handling inputs, updating the UI tree, should be fast enough on one thread.

Re: Advice for the next dozen Rust GUIs

#222

Earlier quoted context omitted.

So that's a good point, but I'm not quite sure OO is the issue. 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 pl…

Isn't it done already? Kotlin plus a simpler OOP toolkit like javafx avoids all those problems. You have a GC to handle circular references, you have a decently strong type system, coroutines etc.

I don’t see why kotlin would be necessary. Javafx is good as is.

Re: Advice for the next dozen Rust GUIs

#223
post #185
post #49

Earlier quoted context omitted.

> it will be a UI toolkit capable of performance completely untouchable by the existing state of the art Could you give an example of an application where the bottleneck is UI code? In my experience the bottleneck is always either disk or network. Not trying to bash you, genuinely curious.

There's plenty of apps that we developers use daily that fall into that. Apps like Teams, Slack and Jira can feel incredibly slow to a lot of people, even with everything already in memory and not waiting for anything from the network or disk. Typing messages, changing tabs, going to read a notification... Facebook sometimes takes a second to show characters you typed in a reply, and the characters often show up out…

I don't have access to such corporate software at the moment, but can you verify in devtools where the delay is actually coming from in the apps you mention? Leaping to "the stack is bad it needs to be rewritten in rust" is extreme, especially when apps like VS Code are generally regarded as non-slothy [1]. Or at least not more slothy than the domain requires [2].

I'd wager the developers are poorly incentivized - if something satisfies the ticket and looks fast enough on their tiny test bed with state of the art hardware and great network (perhaps even localhost), it ships. On the other hand I don't consider something good enough to ship until it is fast enough on testbeds orders of magnitude larger than what I expect a "normal" workflow would include. The process of going from "works" to "fast enough for people using 100x larger inputs than I expect" almost never involves "rewrite in rust"[3], but instead "cache cleverly", "debounce discretely", and if all else fails "sit down and ponder on novel algorithms and data structures". These are all operations that are just as easy, if not easier, in high level languages as compared to rust.

[1]: Full disclosure I was paid to write vscode for a period. When VS Code is slow, and it 100% is at times, the root cause is almost always an extension blocking progress for some dumb reason. This absolutely blows, but isn't a problem rust would solve - indeed extensions can already invoke rust.

[2]: inb4 "but sublime!": Running experiments, I've found sublime to in fact be slower than a fresh VS Code install at working with very large files. Of course when you have extensions trying to do dumb stuff with the big files, VS Code can get worthlessly slow. Again not a problem rust would solve. Try it: make a 5M line file, click it open it in Sublime, then in VS Code. On my machine VS Code opens it well before Sublime can.

[3]: Yes there are some times when rewriting in rust is appropriate, for instance VS Code's search is ripgrep - but rust isn't handling the UI at all, it's running in a separate thread doing what it does best (multithreaded systems programming), while the main renderer thread is doing what it does best (rendering). This is the way forward for the truly "inner loop" code, IMO.

Re: Advice for the next dozen Rust GUIs

#224
post #199

Earlier quoted context omitted.

Yes, so use Rust for all your tree-shaped programming problems. And a GC'd language for everything else. I know if you're holding a hammer it's difficult to not see everything as a nail ...

Or, you use a non-GC language for any application where you care about memory (hint, vast majority of applications fall into this category). GC is imo the single biggest mistake in software engineering.

GC is the only measurable, significant productivity improvement in software development since high-level languages.

Re: Advice for the next dozen Rust GUIs

#225
post #164
post #29

Earlier quoted context omitted.

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…

The DOM still propagates events upwards, resulting in backwards tree-traversal.

In 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.

Re: Advice for the next dozen Rust GUIs

#226

Earlier quoted context omitted.

So that's a good point, but I'm not quite sure OO is the issue. 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 pl…

> though I can't even fathom what that might be. 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 mak…

We do not have such a flawless model for CLIs. Command-line apps have their corner cases as well, and they fail too.

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.

Re: Advice for the next dozen Rust GUIs

#227
post #29

Earlier quoted context omitted.

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…

I don't like React: 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…

I agree that this is an annoying issue. I don't think it's inherent in the FRP UI design, but I think it might very well be somewhat impractical to avoid, especially on the web. The fact is, the DOM already has sort-of 'hidden state' that can't be 'managed.' If you designed a UI framework from the ground up, without worrying about the web, you could avoid some of these pitfalls, for example by making the underlying UI nodes (equivalent to the DOM) completely stateless.

The scroll position, in this case, would just be props.

However, at some point a UI framework usually encapsulates some kind of state somewhere. I'm not sure if a design exists that 100% doesn't encapsulate any internal state. (Maybe immediate mode GUIs?) Though, removing hidden state in the underlying UI components would at least solve the problem of needing to care about underlying node identity for them. But, it wouldn't solve it for components that compose them. I think this is unavoidable in a system that allows state encapsulation.

I think you could make an FRP UI framework that in fact, does not have state encapsulation, but it would be a lot more cumbersome to use, because you'd have to "bubble" the underlying state of any component anywhere all the way up the tree to the root.

Re: Advice for the next dozen Rust GUIs

#228
post #224
post #199

Earlier quoted context omitted.

Or, you use a non-GC language for any application where you care about memory (hint, vast majority of applications fall into this category). GC is imo the single biggest mistake in software engineering.

GC is the only measurable, significant productivity improvement in software development since high-level languages.

Only if you don't care about a decent memory architecture.

And if you don't you'll have to pay for it many times over for the remainder of the products lifetime.

Re: Advice for the next dozen Rust GUIs

#229

Earlier quoted context omitted.

That’s really only a problem if you spend a significant amount of time trying to “build data structures from introductory algos” without reaching for unsafe, though. If you find it easy to build a linked list or graph in C, you can do it just as easily in Rust — use unsafe, and you have your easy linked list, with exactly as much safety as it had in C. Sure, it’s more challenging to build a fully memory and thread sa…

The problem is that unsafe data structures are often less safe (harder to avoid UB) than in C, because in the presence of pointer aliasing and cycles (found in unsafe data structures including BTreeMap's node.rs https://doc.rust-lang.org/src/alloc/collections/btree/node.r... ), Stacked Borrows places strict conditions on constructing &mut T (they invalidate some but not all aliasing *const T). And the user of an owni…

And The “easy” C sophomore computing science graph is inevitably chock full of Undefined Behavior too, the implementers just never noticed or gave a shit because they cobbled something together that looked superficially correct, the compiler didn’t complain, so they decided they were all good. Sophomores, as it turns out, are hardly world-beating experts in C standard esoterica.

The rest of what your wrote is completely irrelevant to the original point: this seems hard in safe Rust only because you’re comparing it to doing something totally different and simpler in C.

Grind your axe about stacked borrows elsewhere.

Re: Advice for the next dozen Rust GUIs

#230

Earlier quoted context omitted.

The problem is that unsafe data structures are often less safe (harder to avoid UB) than in C, because in the presence of pointer aliasing and cycles (found in unsafe data structures including BTreeMap's node.rs https://doc.rust-lang.org/src/alloc/collections/btree/node.r... ), Stacked Borrows places strict conditions on constructing &mut T (they invalidate some but not all aliasing *const T). And the user of an owni…

And The “easy” C sophomore computing science graph is inevitably chock full of Undefined Behavior too, the implementers just never noticed or gave a shit because they cobbled something together that looked superficially correct, the compiler didn’t complain, so they decided they were all good. Sophomores, as it turns out, are hardly world-beating experts in C standard esoterica. The rest of what your wrote is complet…

I agree that sophomores are better off sticking with safe Rust than writing linked lists, but they'll be using libraries written in unsafe Rust, and a "safe" Rust program built on unsound foundations is undefined behavior anyway (through no fault of your own).

You said Rust linked lists have "exactly as much safety as it had in C". Are you seriously arguing that C linked lists are just as wrong as Rust ones, by saying a CS student is as likely to write an incorrect C linked list as a hardened professional is to write an incorrect Rust linked list (eg. Tokio and https://gist.github.com/Darksonn/1567538f56af1a8038ecc3c664a...)? Stacked Borrows ensures that translating sound C code into idiomatic Rust APIs produces needlessly unsound Rust code, and the Rust language (or a specification if it existed) means C translated directly into raw-pointer Rust is unidiomatic and you're fighting the language every step of the way (no autoderef, no -> operator). At this point, an experienced programmer is more likely to write and use a correct C linked list than write and use a Rust one.

Post reply on HN