Hacker News new | past | comments | ask | show | jobs | submit login

Why do you like that? What problems has it helped you solve or avoid?



Not OP, but I agree with them. Here's my take:

If you design your software right, you can use async/await similarly to IO in Haskell—functions that are not async are fast and unlikely to fail, while functions that are async are potentially slow and likely to throw exceptions. This partition can help you reason about and structure your code as you're writing it for solid error handling and minimal duplicate I/O.


Yes but Java is not Haskell.

If you want a monadic IO on the JVM, Scala offers two ecosystems with extremely capable effect systems, providing highly performant runtimes and good (but not perfect) ergonomics.

I've always found async/await bolted on older, mostly imperative OO languages with exceptions to be pretty disappointing. Even modern designs on languages with proper error handling like Rust get their fair share of criticism.

I get that virtual threads will probably introduce surprising bugs and performance issues in some corner cases. But it also removes a whole lot of craziness in the Java ecosystem, namely reactive programming.


Java has checked exceptions, so you don't need anything to signal that it is "likely", you can literally declare it in your code and have the compiler tell you if you're screwing up.


So this might actually make checked exceptions popular again eh? ;)


I know they cause their own problems, but I generally prefer checked exceptions over "read the non-existent documentation" exceptions.


> functions that are not async are fast and unlikely to fail, while functions that are async are potentially slow and likely to throw exceptions.

That would seem like using the wrong tool for the job. If you want to colour functions according to reliability and speed you should use a different mechanism to colour them than a mechanism designed to colour functions based on how they behave if IO blocks.


It feels like that's coupling some concerns together. Functions that do IO are more likely to fail, yes, but that doesn't have to do with their async-ness or their slowness.


It's not that async-ness causes things to fail more easily, it's that if you're going to make a function async it's because it interacts with the outside world in some fashion, and interaction with the outside world is slow and likely to fail.

We could use a different name for that concept to make it more clear why these ideas are related, like `IO`, but in practice async=IO in most code.


It seems like we're on the same page. My point is that your last comment...

> in practice async=IO in most code

does not need to be true. We will never avoid the complexity of IO, but we can avoid the complexity of async, and virtual threads provide us that opportunity.


I didn't mean that = to be transitive. All async is IO, but obviously some IO is not async.

> We will never avoid the complexity of IO, but we can avoid the complexity of async

Because we can never avoid the complexity of IO, having a language construct that makes it obvious when you're using IO is valuable. IO code is different in kind than non-IO code, and having it explicitly marked helps keep the mess that is IO from propagating its problems throughout the rest of your code.


I don't entirely disagree that treating IO as something special at the linguistic level is a good idea, but I do think that async is a wildly indirect and confusing way to achieve that.

Language designers don't add async to make IO look special, they add it as a concurrent programming model.


When IO fails, it doesn't matter a single bit whether the call occured on a virtual or on a platform thread. The likelyhood of failure deserves coloring, but Java already offers a mechanism for that.


A common pattern is to use a single thread executor as one context. Any task scheduled to that context will not run concurrently. When you do it this way, every synchronous chunk (between yields/awaits) is a critical section. So you get critical sections easily, cheaply and with a pretty good syntax.

This pattern is used a lot when you have things like UI which use a single threaded design, or if you need to bind to do some IPC in a single native thread. It's actually very common.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: