This feels a bit like discussing the new fancy garden hoe as a farm hand as they are making the tractor.
Java is a conservative language, which means that it waits and sees which features work well for the tractor, and then retrofits them to the hoe.
Java 20 / JDK 20: General Availability
231–240 of 356 posts
Re: Java 20 / JDK 20: General Availability
#232Earlier quoted context omitted.
Thank you, that's excellent insight into the thought process for the same feature at about the same time. You mention about the human-centred nature of syntax design... do you have any instinct for why one route vs another felt right to users? Do you feel like you've developed a better instinct for this over time, or is it still hard to predict what will feel natural to users?
> do you have any instinct for why one route vs another felt right to users? That's a good question. It is something I spend a lot of time thinking about when I see how users react to a design. In this case, I don't think I have a good answer as to why "when" seemed to go down easier than "if". > Do you feel like you've developed a better instinct for this over time, or is it still hard to predict what will feel natu…
Re: Java 20 / JDK 20: General Availability
#233Re: Java 20 / JDK 20: General Availability
#234Really excited to see how virtual threads are taken up by developers, and if they affect the larger programming language community. They just really seem like "the best of both worlds" to me: the high scalability/low resource usage of async/await, with the ease-of-use experience of threads (e.g. not having to worry about "function coloring").
> low resource usage of async/await Will calling a coroutine do zero heap allocations like async in Rust? > with the ease-of-use experience of threads That's highly subjective. Threads usually require locking which is often hard to get performant and correct at the same time. Async/await allows to write concurrent code with no synchronization.
Well you still need some sort of synchronization, because an "await" allows arbitrary other actions to occur. If an await is introduced in code you transitively call then you might find that some invariant you were expecting to hold has now changed across a call when it previously didn't. Fundamentally, locks are about making invariants atomic and that's independent of exactly how code is scheduled and when.
Re: Java 20 / JDK 20: General Availability
#235Earlier quoted context omitted.
I'm personally not so sure. We already had something like that before (M:N threads), and the world moved away from it, towards letting the kernel manage everything (1:1 threads). So I'd expect instead that operating system kernels gain whatever features are missing for scaling to a higher number of threads, and everything once again goes back to each programming language thread corresponding to one kernel thread.
M:N is not the interesting aspect of virtual threads at all, automagically turning blocking operations into non-blocking is - which has not really been tried before (with erlang and go being the first).
sorry, but Haskell has had it way before Go, with proper STM too. Neither Erlang nor Go are offering the same level of ergonomics for compile-time checked M:N threading.
Re: Java 20 / JDK 20: General Availability
#236Really excited to see how virtual threads are taken up by developers, and if they affect the larger programming language community. They just really seem like "the best of both worlds" to me: the high scalability/low resource usage of async/await, with the ease-of-use experience of threads (e.g. not having to worry about "function coloring").
I'm personally not so sure. We already had something like that before (M:N threads), and the world moved away from it, towards letting the kernel manage everything (1:1 threads). So I'd expect instead that operating system kernels gain whatever features are missing for scaling to a higher number of threads, and everything once again goes back to each programming language thread corresponding to one kernel thread.
Note that this advantage obviously goes away the moment you call into native code. Then the JVM is in the same position as the kernel. It doesn't control the compiler or the stack any more, and so that's why a virtual thread becomes "pinned" at that point and you lose the efficiency (the JVM needs to acquire more kernel threads). Fortunately though the JVM ecosystem doesn't rely on native code all that much, so it should be rare in practice.
This advantage can be brought to other non-Java languages too via Truffle. Truffle languages are reimplemented on top of Java and when programs call into native code they have the option of calling into JIT compiled LLVM bitcode instead of real native code (or indeed any JVM bytecode library). In that situation the JVM remains in control and so things should in theory still be Loom-able. Not sure if that's currently true in practice, but it could be.
Re: Java 20 / JDK 20: General Availability
#237Earlier quoted context omitted.
Var is nice. But I generally prefer to not require people to jump out of the current code to figure out the type of a variable. And yeah, I've worked in those other languages, and navigating unfamiliar code with var everywhere can be confusing, so I try to avoid that kinda thing. Records are nearly useless to me. Immutability is great, but I need a way to derive new sets of information based upon an set of informatio…
`var` in Java is local for a reason. In most contexts I can think of the variable either was created above or was passed in as a parameter/object field. Unless you set it from a weirdly named creation pattern/function. Regarding records, you never had someone update a POJO, add a field, and forget to update equals and hashCode? Sealed classes are great for everything parsing/validation, in data modelling. They're not…
Re: Java 20 / JDK 20: General Availability
#238Earlier quoted context omitted.
I really hope to see the SIMD vector related improvements come through, I know there are some independent JDK code bases that have more evolved SIMD support, but for a lot of big data processing tools, switching away from jdk based languages appears to be the way SIMD related performance improvements have been realized because of this missing crucial feature set. JDK 11 was when this stuff was first in development, a…
Most of these low-level APIs simply just wait for value types - they don’t want to hardcode something into the language, that might not be a perfect fit for those. Which makes sense, frankly.
The odd thing is that part of Valhalla is about how to migrate existing types to being value types, and they already have code that can simulate the same restrictions. So it's not really clear why these features have to wait. Migration is a part of the Valhalla plan anyway.
Re: Java 20 / JDK 20: General Availability
#239Earlier quoted context omitted.
Just adding too, I think some of the switch statement example code is wrong: Object obj = 123L; String formatted = switch (obj) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); default -> o.toString(); }; Unless I'm not understanding something, the default statement should be `obj…
JFC, I was going to say they should have used `String.valueOf(obj)` since I expected `Object obj = null; switch (obj) { default ->` to do something sane but no, the stupid PoS NPEs because `switch` itself evidently calls `Objects.requireNonNull` The Billion Dollar Mistake meets the Power of Compounding Interest to produce an inflation adjusted number that just keeps on giving
See [1] for more.
Re: Java 20 / JDK 20: General Availability
#240Really excited to see how virtual threads are taken up by developers, and if they affect the larger programming language community. They just really seem like "the best of both worlds" to me: the high scalability/low resource usage of async/await, with the ease-of-use experience of threads (e.g. not having to worry about "function coloring").
> low resource usage of async/await Will calling a coroutine do zero heap allocations like async in Rust? > with the ease-of-use experience of threads That's highly subjective. Threads usually require locking which is often hard to get performant and correct at the same time. Async/await allows to write concurrent code with no synchronization.
Hmm,I don't see how async/awaits makes a difference. Care to explain?
Like, if you have multiple sources that can add or read from a queue, unless there is a single thread running all your async loops (ala python), you still need some synchronization. At least that's my experience using coroutines heavily in kotlin.