3 ms·
I will forever argue that things like goroutines and the Java Loom Project are proving that it is long term more successful than making an explicit async keywor
by no_wizard 3y ago
I will forever argue that things like goroutines and the Java Loom Project are proving that it is long term more successful than making an explicit async keyword / operation that has its own semantics when invoked, because it won't dictate your code and cause the color function problem to exist.
I'd love to see this in Rust, and I know that it initially had something like this, perhaps its not a bad idea for someone to take a second look at this now that more time has passed.
EDIT: to be clear, that is not me saying we need goroutines or we need a Java Loom equivalent in Rust, simply, the DX of these two examples are far superior to the DX of async Rust today, in my opinion
- withoutboats3 3y agoThis was the subject of my previous post: https://without.boats/blog/why-async-rust/ https://without.boats/blog/why-async-rust/
- insanitybit 3y agoHow can you argue that? Loom is extremely early, it's not proving anything. And Java/Goroutines don't have a keyword because they do things implicitly, they have heavy preemptive runtimes.
- no_wizard 3y agoThats red herring IMO. Sure, they're GC'd languages, but that does not preclude the fact that both of these approaches from a DX perspective are easier to work with, and that matters in language design. I didn't say we need goroutines or we need Loom style asynchronous primitives I am however pointing out, that they did a really good job of making async approachable and feel like you're writing the same code as you would in a traditional synchronous model. Thats the real win. Its not an easy problem to solve, to be absolutely clear, but its a worthy goal, and if that means it adds marginal overhead initially I think its worth the tradeoff (esp. if you can do something similar to how you can use Rust in a `no-std` build, you could do one without a `async runtime` build, spitballing off the top of my head) Another problem is that generally speaking, async is de facto used a 3rd party lib, and it really should be a first party primitive that everyone feels comfortable using. To me, this is what matters
- steveklabnik 3y ago> both of these approaches from a DX perspective are easier to work with, and that matters in language design. While you are right that DX matters, DX is not the only thing that exists. Design is about balancing constraints and tradeoffs. Rust has other design commitments that preclude using this design, before you even get to DX questions. (Furthermore not everyone agrees that these things are clearly better from a DX perspective, as DX is a subjective topic.)
- no_wizard 3y agoI agree, there's questions that need to be answered, and I don't know that I even have answers to give to them. I will say, that its clear, to me and a good portion of Rust users, that async in Rust needs DX improvements. Its one of the top features of the language that is used alot and people struggle with often[0] [0]: To be fair, async in any language trips up developers pretty often, though I think Rust can give someone a particularly bad time. Granted, I have not compared it to C / C++ as I don't do any development in either language currently
- steveklabnik 3y ago> I don't know that I even have answers to give to them. To be honest, this is why this discussion always gets frustrating: people demand change that is impossible, and then when pushed for how to accomplish the impossible, they throw up their hands. I do not think you or anyone else is doing it maliciously, but for some reason, on this specific topic, it happens endlessly.
- no_wizard 3y agoMy best shot at this is something akin to a runtime built-in to the stdlib that can be opted out, similar to how you can build something with `no-std` so there is no reliance on `libstd`. Perhaps this is a great place where you drop into more "raw" async programming using the async / await primitives. You lose DX sugar but slim out the runtime for embedded work. Ideally, the runtime could handle anything written using lower level primitives as to not completely kneecap libraries that need to work with `no-async-runtime` (or whatever you want to call it). This would at least alleviate a common concern I hear around this, which is runtime bloat. That seems like a step in the right direction to integrate a unified async runtime with an alternative / better syntax[0] [0]: I want to note, that C# is the only language I ever worked in that supported async in two constructs. There is the traditional async / await, which is by far the most common. Before that though, there was event driven async programming (with support for background workers and other async features) and that is also still supported, and they can interop with each other (with some caveats)
- zozbot234 3y agoGoroutines and the Java Loom are just fibers. They're like a super clunky mix of async-like and thread-like features, though sometimes there are reasons to use them. (For example, stackful fibers might enable cleaner interactions with OS facilities or outside library code.) Rust makes it real easy to just use threads if that's what you prefer.
- jayd16 3y agoAsync handles thread contexts better. Maybe I'm out of the loop but implicit blocking patterns haven't taken over gui programming just yet.
- samus 3y agoLoom is very new, and Java on the desktop is almost dead. Even though virtual threads could be useful for GUI programming, I don't expect significant innovation in that area. But the upcoming Structured Concurrency[0] and Scoped Values[1] JEPs make things hopefully easier. [0]: https://openjdk.org/jeps/462 https://openjdk.org/jeps/462 [1]: https://openjdk.org/jeps/446 https://openjdk.org/jeps/446
- jayd16 3y agoStructured concurrency looks good but is it really better than async syntax?
- samus 3y agoI have to admit that async syntax has a certain charm, as it has deep connections to iterators. (I have to program with Unity for my master thesis). But Structured Concurrency leverages well-known blocking syntax that doesn't require further explanation. It's not even specific to virtual threads.