Live data from Hacker News

Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

jvm-weekly.com

201–210 of 464 posts

Re: Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

#201
post #80

Earlier quoted context omitted.

This. C# was basically always meant to be "Java but done right". It came several years later, after Microsoft was legally barred from "EEE"-ing Java and required a direct competitor.

> It came several years later, after Microsoft was legally barred That is an eloquent way of re-writing the history of Microsoft stealing Java and not being allowed to get away with it.

They didn't "steal" anything, iirc; they started as a legitimate licensee and then tried their usual embrace/extend/extinguish as "J++" (the EEE I mentioned). Sun sued for breach of license and won, barring Microsoft from extending Java outside of the (Sun-controlled) process. So they dropped it and built their own version, with blackjack and hookers.

Re: Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

#202
post #132

Earlier quoted context omitted.

C# actually has a fair amount of gotchas and Java aims to make these explicit. So where C# mostly copied C from a low level perspeCtive, the Java guys approached this high level and analyzed in detail which constraints give you what kind of benefit. So where in other languages, the struct/class taxonomy is binary, Java allows more granular control, reflection the semantics of the underlying domain. Snd as it turns ou…

Could you actually explain/exemplify any of the gotchas and what's been made better (or is this just handwaving)?

Part of the reason Java hasn't reified generics is because C# did and it was a real big headache that also limited non-C# languages on the C# runtime (CLI?). Everything had to be recompiled to work with newer C# runtimes. While it's pretty easy to run a bunch of language on the JVM (Javascript, python, ruby, clojure) doing the same for C# is somewhat a nightmare, particularly for non-type aware languages.

For example, Imagine you have an api like `void do(List foos)`. In the erasure environment of the JVM that looks like `void do(List foos)`. From python it's pretty easy to call with a `foos = [Foo()]`. But not so much if your python implementation needs to figure out how and if it can coarse it's `List` type into a `List` type.

Re: Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

#204
post #195

Earlier quoted context omitted.

new Integer(10) == new Integer(10) // true Before value classes this would always be false. The only time comparing Integer objects with == could be true is if Integer object was create by going through Integer.valueOf (or obviously if they were the same object reference.) By default the cached values where -127 to 127, but that is tuneable at runtime. https://github.com/openjdk/jdk/blob/jdk-27%2B27/src/java.bas...

So you've made my point in showing how complex this is because you're incorrect [1][2]: > By default, Java maintains a cache of Integer objects for values between -128 and +127. [1]: https://stackoverflow.com/questions/3130311/weird-integer-bo... [2]: https://dev.to/marzuk16/understanding-integer-caching-in-jav...

it's easier to remember that it originated from the Byte range, where all bytes could be kept in. Character didn't have negative values so it did [0-128) instead. Long and Short are the same as Byte.

Years before the autoboxing/Integer.valueOf() caching stuff (and before generics), (I) used to have IntegerProvider that did similar stuff to higher ranges. Personally, I have considered autoboxing on integers net-negative for Java

Re: Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

#205
post #115

Earlier quoted context omitted.

Which recently decided that Go was a better option than C# for the Typescript rewrite, exactly because not all decisions were done correctly to make C# a better fit for the problem.

Go was chosen mainly because it aligned more with how the existing compiler is designed. They did not want to redesign the compiler which eliminated C# as a choice. So Go is apparently just a better fit for quickly porting JavaScript code to.

That was the original motivation yes, although they acknowledged later that the weaker type system from Go required redesigning the data structures anyway.

And as proven in the recent announcement, they had to rewrite parcel from C++ into Go, as they didn't found a comparable library in Go ecosystem.

There is also another interview, where again they mention having used AI as tool for code rewriting as well.

Also to note that it was pointed out that Native AOT wasn't up to the job, again something that both Java and C# failed not having done it properly from day one.

Re: Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

#206
post #196

> But the difference in memory is fundamental. The JVM can now store the values themselves in the array, laid out densely one after another: 8 bytes per point (plus a possible null flag), in a contiguous block. No headers per element. No pointers. No jumping around the heap. How much was this article proof-read? Didn't they just get finished talking about how heap flattening won't work for objects with > 64-bit repre…

> No headers per element. No pointers. No jumping around the heap. that smells of AI [1], and thus lazy writing. I'm all in for using AI to help you write, but if you don't put your voice to it then there's no reason to read it. [1] https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing#...

Also, the images were ruinously far off from what they intended to convey. Dude, just draw a picture by hand & take a picture of it.

Re: Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

#208
post #196

> But the difference in memory is fundamental. The JVM can now store the values themselves in the array, laid out densely one after another: 8 bytes per point (plus a possible null flag), in a contiguous block. No headers per element. No pointers. No jumping around the heap. How much was this article proof-read? Didn't they just get finished talking about how heap flattening won't work for objects with > 64-bit repre…

> No headers per element. No pointers. No jumping around the heap. that smells of AI [1], and thus lazy writing. I'm all in for using AI to help you write, but if you don't put your voice to it then there's no reason to read it. [1] https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing#...

That particular section is indeed AI, though other parts of the article aren't: https://www.pangram.com/history/89b28cd1-58e6-4065-9f1d-111a...

Re: Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

#209

> But the difference in memory is fundamental. The JVM can now store the values themselves in the array, laid out densely one after another: 8 bytes per point (plus a possible null flag), in a contiguous block. No headers per element. No pointers. No jumping around the heap. How much was this article proof-read? Didn't they just get finished talking about how heap flattening won't work for objects with > 64-bit repre…

18446744073709551616 possible values and you can't spare 1 for null? :)

TIL that Rust has NonZeroU64 which you can combine with Optional to get the required behaviour with only 64 bits per entry. [1]

[1] https://doc.rust-lang.org/std/num/type.NonZeroU64.html

Re: Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28

#210
post #197

I found a solution for what seems to be the same problem, in a different language: a particular type of lists, where the class metadata is stored once and the data for each instance is contiguously stored in a flat array. Not sure if it covers exactly the same terrain, but perusing the article, it seems to be the case, with a single instance being the degenerate case.

Yup, it's the same terrain.

I've made something like this in the past. And I did it exactly because `List` was too expensive and slow.

    class FooSOA extends Collection {
      double x[];
      double y[];
      double z[];
      
      Foo get(int index) { return new Foo(index); }
      
      record Foo(int index) {
        double x() { return FooSOA.this.x[i]; }
        double y() { return FooSOA.this.y[i]; }
        double z() { return FooSOA.this.z[i]; }
      }
    }
Post reply on HN