Live data from Hacker News

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

jvm-weekly.com

171–180 of 464 posts

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

#171

Earlier quoted context omitted.

It could also be true if the instances were created through auto-boxing (e.g. arrayList.add(10); arrayList.add(10); arrayList.get(0) == array List.get(1) //would return true, but false if you used 1000 instead of 10).

Yes, because auto-boxing is just compiling to Integer.getValue under the hood, the bytecode for Integer.getValue(1) and ((Integer) 1) is the same. They'll both compile to something like: iconst_1 invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer

Sure, I was just talking about Java syntax, not the bytecode internals.

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

#173
post #94

Earlier quoted context omitted.

How would a non-nullable class field work in Java when it can be initiqlized by arbitrary imperative code that can read it while it's being initialized?

Look at how Go did it. Any value type has a defined 0 value, and any variable of field of that type is initialized to 0 by default. So any un-initialized non-null able value type field could have the corresponding 0 value.

That's worse than null. Now every object has an invalid state. It works for Go because Go is trying to keep language complexity low. It has no good design principles behind it other than that. Also the zero value of a reference is null so you still haven't answered how a non-nullable reference field would work.

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

#175
post #94

Earlier quoted context omitted.

How would a non-nullable class field work in Java when it can be initiqlized by arbitrary imperative code that can read it while it's being initialized?

How can Kotlin do it?

Probably with hacks. Did you know a final field in Java can change its value? And I'm not talking about his reflection to make it non-final. With ordinary code only, you can read a final field before it's been initialized, so it still holds its default zero value. For example "final int x = calcX();" and have calcX print the value of x, it will be zero.

There's a whole bunch of specification language describing how constants aren't actually constant in specific situations.

I don't know Kotlin but I assume it does the same thing: until the non-nullable field gets initialized, it holds null and violates the type system.

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

#176
I'm a little unclear as to when and under what conditions this results in non-heap objects, now (<= 64-bits?) and in the future (???). I thought that was the _ENTIRE_ point of this project, so I was surprised to see they can be null (did that change from before?). If it is always and forever limited to 64-bits, I fail to see the point of this entire project, as it would have been far simpler to add syntactic sugar (simply pass primitives underneath the covers) as Scala did to create value types vs. JVM changes.

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

#177

Earlier quoted context omitted.

Look at how Go did it. Any value type has a defined 0 value, and any variable of field of that type is initialized to 0 by default. So any un-initialized non-null able value type field could have the corresponding 0 value.

That's worse than null. Now every object has an invalid state. It works for Go because Go is trying to keep language complexity low. It has no good design principles behind it other than that. Also the zero value of a reference is null so you still haven't answered how a non-nullable reference field would work.

Sorry, I misinterpreted your question to be about non-nullable value classes, not non-nullable classes more generally. For reference variables, it seems that the a priori best approach would have been to generate a compiler error if the field was read before it was written; since this ship has long since sailed with final fields, it seems that the same approach would have to be taken - the "not null able" guarantee only applies after the class is fully initialized, and you can observe it as null during initialization. This is probably not a huge problem, given that initialization code always has to deal with a class breaking its invariants, since they are only established at the end of initialization.

Regarding the 0 value choice in Go, I don't agree that this is worse than null. It simply applies a design constraint that is not usually very hard to satisfy - that the 0 value of your type must have well defined semantics.

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

#178
post #115
post #51

Earlier quoted context omitted.

It's no mystery. https://en.wikipedia.org/wiki/Anders_Hejlsberg

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.

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

#179
post #46
post #34

Earlier quoted context omitted.

My point is that pass by copy and pass by value do the same thing, they copy the value representation. In other words, pass by copy means exactly pass by value.

Actually, Java only has pass-by-value, even for reference types. (The same way as C does). People really misuse/misunderstand this term: Java objects are passed by their pointers ("references") being copied. The alternative is pass by reference, which is done by e.g. c++, rust, who actually have references (Java doesn't). A good litmus test is whether you can write a swap method that actually changes your local varia…

Rust is also “pass reference by value,” not pass by reference.

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

#180
post #39

Earlier quoted context omitted.

Sealed classes/interfaces and records are proper sum and product types. The stdlib's Option type predates this language update by a long shot, so it doesn't use sealed classes, but it is now possible to have the usual FP "Maybe" type in Java: ``` sealed class Maybe permits Some, None { record Some (T obj) {} record None() {} } ``` (You will probably have to write Maybe.Some and I might have messed up the generic synt…

Except this is completely wrong. First, a record can't extend anything, it's not even valid syntax, so a sealed class can't permit record subclasses. So no, it's not possible to create a Maybe class in Java that can only represent a Some or a None record. You could do it with regular classes, or if it's ok for Maybe to be an interface. Secondly, regardless of the sealing, nothing in any current or near future of Java…

Mistyped, it's sealed interface.

> So you can always have `Maybe x = null`, or even `Some x = null`.

Yeah and? Practically every type system have escape hatches, like Haskell can also do side effects without the IO monad, does it make the latter useless?

Post reply on HN