Live data from Hacker News

Project Loom and Structured Concurrency

javaadvent.com

41–50 of 111 posts

Re: Project Loom and Structured Concurrency

#41
post #37

Earlier quoted context omitted.

Yes, and even on a per-thread basis.

Thanks! Is there an example "Hello World" executor that demonstrates the minimum functionality needed? I would like an executor that runs all tasks on a single thread and schedules them deterministically for testing.

    var myThreadFactory = Thread.builder().virtual(Executors.newSingleThreadExecutor()).factory();
All threads created by this thread factory will be scheduled to the same kernel thread.

Re: Project Loom and Structured Concurrency

#42

Earlier quoted context omitted.

> Since the article goes out of its way to not mention Kotlin, "Since the article goes out of its way to not mention [Rust|Kotlin]" and "I'm surprised this article has no mention of [Rust|Kotlin]" must be one of the most frequently used templates on HN.

The difference is that Kotlin has been gobbling up Java users using Java frameworks like Android and Spring. Coroutines are used in both and implement structured concurrency exactly like Loom does. It's not a little bit similarish and vaguely related: it maps 1 to 1 conceptually; well at least for the stuff that Loom actually implements. Rust indeed would deserve a mention as well but it follows a somewhat different…

I think that Kotlin's existence has really given Java a kick in the pants. I agree that there has been a lot of people picking up Kotlin because of how verbose and "last century" programming in Java feels. Modern (static typed, imperative, algol-like) languages are so much more ergonomic (Rust, Go, Kotlin, Swift, TypeScript, etc), that it's kind of painful to go back to Java, with its silly "everything has to be an object, except we still have unboxed primitives for some reason", etc.

On the other hand, to their credit, the Java devs (Oracle, I guess) have really stepped up their game in response. Java just (fucking finally) got "records" (better than data classes, IMO), and sealed classes. Soon they'll have virtual threads. And some day they may actually have what I think they call "value types" (bad name), which will be excellent news.

With these things, they've implemented basically all of Kotlin's "must have" features except for null safety and clean, sexy, syntax. If they ever tack on some kind of "strict null mode" to Java, that might just be the end of Kotlin. Everyone who wants a functional JVM language will go to either Scala or Clojure, and the rest can stay on Java. That is, unless of course, the Kotlin guys pull more tricks out of their sleeves. But, in all reality, the entire purpose of Kotlin seems to have been to have a middle-ground between Java and Scala while learning from the mistakes of both. If those languages also learn from their own mistakes (they are), then Kotlin is in trouble.

Re: Project Loom and Structured Concurrency

#43

I am still not comfortable enough with this concept to answer this question myself, but will this, by default, lead to speed ups and/or reduced resource consumption in a) application server like tomcat and b) web frameworks like Spring? Assuming it's implemented...

It depends a lot on how the service handles requests. If it takes the one thread per request model, and those requests are mostly bound by blocking calls like IO, then replacing those OS level threads with virtual threads will almost certainly see a reduction in resources (as virtual threads are smaller) and potentially more consistent response times (because scheduling the correct thread is easier at the JVM level).

However if your service has been written in an async style, or you are mostly CPU bound, then you aren't likely to see a change.

Our hope is that by making simple blocking code perform better you won't have to spend your time converting code to an async style to scale your services.

Re: Project Loom and Structured Concurrency

#44
post #33

Earlier quoted context omitted.

It's more than that. Java developers are switching to Kotlin; notably on Android and Spring code bases (well over 50% of backend Java projects at this point apparently). This is an article about structured concurrency and how Loom implements something that Kotlin has shipped that both Android and Spring heavily integrate with already. So, there's more than a casual relation between Kotlin co-routines and Loom. I'd go…

> So, there's more than a casual relation between Kotlin co-routines and Loom. Not beyond the fact it was one of the things we looked at and decided to go in a completely different direction. We looked at Python, Go, JavaScript, C#, Kotlin, C++, Rust, Zig, Haskell, Pony, Scheme, Erlang, Céu, Scala and Clojure, and decided not to go down the C#/Kotlin path, which is why we ended up with a solution that is nothing alik…

> Syntactic coroutines, on the other hand, were something to avoid.

Could you articulate or point me to some of the arguments or thoughts that lead to the conclusion here? I know and understand the term "colored functions", but I'd love to read a real analysis of the pros and cons of colored functions, because I personally go back and forth on whether I think they are bad or good. On the one hand, having a function that is explicitly marked as "this thing needs to be treated specially because it may block for a long time" is actually kind of nice. On the other hand, it's hard to write generic functions/tools when you have to handle different colored closures, for example. Also on that hand is the fact that I can still write a function as the "wrong color" if I'm inept.

Or was that decision based on something other than language semantics?

> There are certainly languages we consider serious competitors, but Kotlin is still an order of magnitude in size away from being one of them.

Just out of curiosity, what are those languages? C#? PHP?

Also, this statement makes you sound like Goliath. I don't disagree with you that Kotlin, in particular, is probably not a huge "threat" to Java. But you're slinging numbers like a politician or a PR person: "Kotlin, which has reached ~2-4% on the Java Platform, and might even reach 5-7% some day". Java has 25 years of legacy- are you seriously saying that picking up 5% of JVM code in The truth is that until pretty recently, Java was really lagging behind and many devs were cursing their fate that they were still working on Java projects. Java 8 was a huge leap forward, and Java 15 is another sizeable leap. So I suspect that Java will stop the bleeding. But it was not at all guaranteed to stay a behemoth, IMO.

> Nope. First of all, Kotlin doesn't have records. Kotlin-like data classes were something we looked at (we look at all languages) and said, we don't want that, we want records. Second, the inspiration for records was ML. So records are actually yet another example where we decided not to go in the same direction as Kotlin. This isn't to say Kotlin did something worse or better, but it did do something decidedly different.

I haven't used them yet, but I think that records look better than Kotlin's data classes. But the only difference I see is that they don't auto-generate a `copy()` method, like Kotlin's data classes do. I believe that was a big mistake on Kotlin's part. Is there some other way that Java records are different than data classes? Because if that's the only difference, it sounds really disingenuous to suggest that records are not inspired by data classes. Like, what are the odds that it took until 201x for you (all) to decide to copy records from ML? You certainly didn't do it before Kotlin for some reason.

Re: Project Loom and Structured Concurrency

#45
post #40

Since the article goes out of its way to not mention Kotlin, I'll do it for them since this is both lame and more than a bit disingenuous. Arguably, Kotlin co-routines (and the Flow API) provides a very nice implementation of the exact same concepts on the JVM. As far as I know, the loom integration is already planned and probably implemented to a large degree. Mostly doing that should be straightforward as this pret…

You're getting downvoted because of your snarky opening statement. But I do think it's important/relevant to compare virtual threads to Kotlin coroutines. I agree with your point that tacking all of this onto the existing (flawed) Thread API is a risky move. I understand the reasoning on both sides, but I'm not usually a huge "backwards compatible at all costs" or "don't make people learn new things" proponent on any…

> I agree with your point that tacking all of this onto the existing (flawed) Thread API is a risky move.

This is not what Loom does, though. Virtual threads are not using the thread API. They are (Java) threads; no more and no less than today's threads. Just as people don't normally use the java.lang.Thread API directly to use today's threads, there's no reason why they should use it with virtual threads.

> One advantage that colored functions do have is that you see it and "know" that the thing involves expensive and/or blocking work.

It gives you the illusion of knowing something that you don't really. The OS, or the Java runtime, can and do pause your thread at any point for durations that are between orders of magnitude shorter and orders of magnitude longer than some blocking operations. There is no useful semantic knowledge you can extract from knowing something is "blocking" to the point that it's a meaningless designation. It does mean something in "single-threaded" languages like JavaScript, or when programming hard realtime software, but not in ordinary Java. You're wasting a syntactic "colour" on zero bits of information.

Re: Project Loom and Structured Concurrency

#46
post #42

Earlier quoted context omitted.

The difference is that Kotlin has been gobbling up Java users using Java frameworks like Android and Spring. Coroutines are used in both and implement structured concurrency exactly like Loom does. It's not a little bit similarish and vaguely related: it maps 1 to 1 conceptually; well at least for the stuff that Loom actually implements. Rust indeed would deserve a mention as well but it follows a somewhat different…

I think that Kotlin's existence has really given Java a kick in the pants. I agree that there has been a lot of people picking up Kotlin because of how verbose and "last century" programming in Java feels. Modern (static typed, imperative, algol-like) languages are so much more ergonomic (Rust, Go, Kotlin, Swift, TypeScript, etc), that it's kind of painful to go back to Java, with its silly "everything has to be an o…

Kotlin was created circa 2010 as a result of Java's stagnation in Sun's dying days. Oracle has since increased investment in the platform. So Java's resurgence and Kotlin's appearance are both a response to the same event rather than one causing the other.

Re: Project Loom and Structured Concurrency

#47
post #45
post #40

Earlier quoted context omitted.

You're getting downvoted because of your snarky opening statement. But I do think it's important/relevant to compare virtual threads to Kotlin coroutines. I agree with your point that tacking all of this onto the existing (flawed) Thread API is a risky move. I understand the reasoning on both sides, but I'm not usually a huge "backwards compatible at all costs" or "don't make people learn new things" proponent on any…

> I agree with your point that tacking all of this onto the existing (flawed) Thread API is a risky move. This is not what Loom does, though. Virtual threads are not using the thread API. They are (Java) threads; no more and no less than today's threads. Just as people don't normally use the java.lang.Thread API directly to use today's threads, there's no reason why they should use it with virtual threads. > One adva…

> This is not what Loom does, though. Virtual threads are not using the thread API. They are (Java) threads; no more and no less than today's threads. Just as people don't normally use the java.lang.Thread API directly to use today's threads, there's no reason why they should use it with virtual threads.

Right. That's fair. They are threads, but it's just that now you have two "kinds" of Thread, where before you had one (AFIAK). I like the analogy to "virtual memory" of an OS, but can applications ask for "real RAM" instead of "virtual RAM"? I don't think so, but I could be wrong. So having virtual threads and "raw" threads under the same class has pros and cons, IMO.

> It gives you the illusion of knowing something that you don't really. The OS, or the Java runtime, can and do pause your thread at any point for durations that are between orders of magnitude shorter and orders of magnitude longer than blocking operations. There is no useful semantic knowledge you can extract from knowing something is "blocking" to the point that it's a meaningless designation. It does mean something in "single threaded" languages like JavaScript, but not in Java.

That's true. But it's still a signal from the author of the function, the same way a type is. If a function makes a network call, you can be fairly sure that it will usually take longer to return than a function that is just flipping some bits around (even a fairly large amount of bits). Or do you still disagree? Would you say that if I'm writing JVM code, I really shouldn't worry about what functions make network and DB calls or what thread they're on because it really doesn't matter? Even if I have a UI that I'd like to keep responsive?

Re: Project Loom and Structured Concurrency

#48
post #44
post #33

Earlier quoted context omitted.

> So, there's more than a casual relation between Kotlin co-routines and Loom. Not beyond the fact it was one of the things we looked at and decided to go in a completely different direction. We looked at Python, Go, JavaScript, C#, Kotlin, C++, Rust, Zig, Haskell, Pony, Scheme, Erlang, Céu, Scala and Clojure, and decided not to go down the C#/Kotlin path, which is why we ended up with a solution that is nothing alik…

> Syntactic coroutines, on the other hand, were something to avoid. Could you articulate or point me to some of the arguments or thoughts that lead to the conclusion here? I know and understand the term "colored functions", but I'd love to read a real analysis of the pros and cons of colored functions, because I personally go back and forth on whether I think they are bad or good. On the one hand, having a function t…

> Could you articulate or point me to some of the arguments or thoughts that lead to the conclusion here?

I gave a talk about exactly that recently at Code Mesh. I expect them to post the video soon. https://codesync.global/speaker/ron-pressler/#745why-user-mo...

> Also, this statement makes you sound like Goliath.

Maybe, but it's not just a matter of size but also trajectory. And, as you say, our competition is mostly off the Java platform. My point wasn't to brag, but to put matters in perspective. There are dozens of nascent languages, the vast majority of which will never make it to the top ten, let alone the top five. And while a few of them will, no doubt, one day unseat the incumbents, we obviously don't think of all of them as "threats."

> what are those languages?

The obvious ones. It's not that we don't know that some smaller languages will one day become big, some will even surprise us all, but extrapolating early growth to long-term success is certainly not a good model.

> Like, what are the odds that it took until 201x for you (all) to decide to copy records from ML? You certainly didn't do it before Kotlin for some reason.

As I wrote in another comment, Kotlin's arrival and Java's "boost" are both a response to the same event: Java's decline in Sun's dying days. Once Oracle increased investment, it was mostly a matter of prioritising which features to do first. Records were seen as less urgent as lambdas, so they came later.

Re: Project Loom and Structured Concurrency

#49

Since the article goes out of its way to not mention Kotlin, I'll do it for them since this is both lame and more than a bit disingenuous. Arguably, Kotlin co-routines (and the Flow API) provides a very nice implementation of the exact same concepts on the JVM. As far as I know, the loom integration is already planned and probably implemented to a large degree. Mostly doing that should be straightforward as this pret…

What makes you think that Kotlin should be mentioned? Especially since concurrency in Kotlin is really not great, compared to concurrency in Erlang or Scala.

I'm not familiar with concurrency in Erlang or Scala, could you explain how it differs from the approach in Kotlin (which I know)?

Re: Project Loom and Structured Concurrency

#50
post #34

I have a lot of experience using concurrency in Go, and for the last couple years have been at the bleeding edge of Python async. The tradeoffs between the two approaches are immense. With the virtual thread model you have: * No function coloring problem. This also means existing code is easier to port. * possibility of transparent M:N scheduling. * Impedence mismatch with OS primitives. * Much more sophisticated run…

I don't think "task cancellation" is quite the major difference you think. If you model it as thread A wants to cancel thread B, then while threading means that A runs and cancels B, but B may need some time to catch up, the async world has the problem of thread A running at all to cancel B, if B is having a problem that requires cancellation. It's "obvious" and "safe" until it doesn't happen at all. This is a pervas…

> but if you want to see a runtime that really has the asynchronous exceptions thing figured out, go look at Erlang.

The erlang VM does indeed have async exceptions, and resource management figured out. Usually you can just kill an erlang process and you don't have to clean up after it's open sockets, file descriptors, etc.

It's also possible to hook the C FFI system to take full advantage of that: https://youtu.be/l848TOmI6LI

(Disclaimer: self promotion)

Post reply on HN