Comment by revetkn
10 hours ago
Regarding "What's wrong with what .NET did with threads?", see https://cr.openjdk.org/~rpressler/loom/Loom-Proposal.html (relevant part below):
An alternative solution to that of fibers to concurrency's simplicity vs. performance issue is known as async/await, and has been adopted by C# and Node.js, and will likely be adopted by standard JavaScript. Continuations and fibers dominate async/await in the sense that async/await is easily implemented with continuations (in fact, it can be implemented with a weak form of delimited continuations known as stackless continuations, that don't capture an entire call-stack but only the local context of a single subroutine), but not vice-versa.
While implementing async/await is easier than full-blown continuations and fibers, that solution falls far too short of addressing the problem. While async/await makes code simpler and gives it the appearance of normal, sequential code, like asynchronous code it still requires significant changes to existing code, explicit support in libraries, and does not interoperate well with synchronous code. In other words, it does not solve what's known as the "colored function" problem.
Regarding Swing, virtual threads are "just" threads so no reason they (and structured concurrency) can't be used.
So does Java provide an API for continuations or just the virtual threads hidden behind the threading API? You can't use threads to wait for something on the UI thread (which is why e.g. SwingWorker exists), but you can with await.
The colorless functions approach has well-known disadvantages though, including providing less control and making interop a pain. It isn't like one approach is the correct one and another is a mistake.
> including providing less control and making interop a pain
This is true in some languages but not in Java. The limitations (and performance cost) are not from the nature of continuations/stackful coroutines/"colourless functions", but from their interaction with other constraints and existing designs in the language. E.g. in Java, virtual threads have zero impact on FFI.
In general, the costs and limitations associated with a feature in language X don't extrapolate to language Y, because they often stem from interaction with existing constraints in language X.
The design of FFI is a very common source of problems for various features. For example, if the FFI is designed such that you frequently pass pointers to to objects to C, that can have a big impact on other features. In Java, you nearly always only pass pointers to "off heap" memory, i.e. memory that's not managed directly by the JVM. While this has no performance cost, you could say that this, in itself, has some convenience cost, except Java programs need to rely on FFI much less than other languages, so the overall cost to convenience is low.