<div dir="ltr">I haven't read the description of binary compatibility between Q type and L type anywhere.<div>I have made several attempts on LW4, but the attempt to change the L type to Q type in the API method signature always causes NoSuchMethodError to be thrown when calling it.<br></div><div>Of course, I know that the implementation of the primitive class is still incomplete. <br></div><div>However, I haven't seen any description of the migration scheme so far, so I'm worried about it.<br></div><div><br></div><div>I'm very surprised that you have questions about Valhalla breaking compatibility. Am I misunderstanding JEP draft 8261529?<br></div><div>What I've learned from reading this draft is that Universal Generics will cause a large portion of existing code to have null pollution warnings and be completely broken in the future.<br></div><div>Also, parts of the code require the use of new language features to eliminate null pollution. This is a big obstacle to migration.<br></div><div><br></div><div>When we talk about migration, a lot of times it's not Java 8 to Java 25 (assuming we can see Valhalla in Java 25), and often what we need is to migrate from Java 8 to Java 8: </div><div>We want the migrated code to continue to compile on Java 8, but at the same time to fit Java 25 as perfectly as possible.</div><div>This is a fairly common requirement, since most third-party libraries distributed through maven repositories want to work on as many Java versions as possible.<br></div><div>I know that multi-release jars can help us achieve this, but it is not easy to use and will cause too much trouble, so many projects try to avoid this as much as possible.<br></div><div>Therefore, requiring users to use new language features, I think, is extremely disruptive.<br></div><div><br></div><div>Let's get back to Universal Generics. It breaks so much generic code to introduce the concept of non-nullable types.<br></div><div>This seems unavoidable, because the difference between value types and reference types exists objectively.<br></div><div>But I'm sad that it's causing so much trouble just for primitive classes. That's why I sent this email.</div><div><br></div><div>If my previous words mean "it's easy to make non-nullable types", I apologize for my inaccurate expression.<br></div><div>I know this is not an easy thing to implement, such as default values and thread safety issues are issues to consider.<br></div><div>I'm glad to know you've been experimenting, but please forgive my dissatisfaction with the current draft of primitive classes and universal generics, which I think is causing too much confusion and disruption.<br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Nov 28, 2022 at 10:04 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" target="_blank">brian.goetz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">There’s a lot of good thoughts in here (and some wishful thinking too), but most of it is well-covered ground.  <br>
<br>
> After I read the JEP and related documents of Project Valhalla, I doubted the necessity of the existence of primitive classes.<br>
<br>
We have been asking ourselves this question every day.  As the old saying goes, things should be as simple as possible, but no simpler.  Past attempts to simplify them away did not succeed, but that doesn’t mean we don’t keep trying.  <br>
<br>
> It is impossible to migrate from identity class to primitive class, which will break binary compatibility.<br>
<br>
This is not entirely true.  There are constraints involved, and at the appropriate time we will publish a migration guide, but it is not the case that you can’t migrate from B1 to either B2 or B3.  But this isn’t your real point.  <br>
<br>
> At the same time, in order to support non null types, the universal generics draft also greatly undermines compatibility.<br>
<br>
This is a pretty strong statement, and I’ve certainly not seen evidence for this.  But, again this is tangential to your point (and likely overstated to make your point sound better, though there’s no need for that), so let’s get to your point.  <br>
<br>
> Although the value class is more compatible, it may not be inlined when it is a field or array member.<br>
<br>
You’re confronting the essential physics of the problem; rejigging the packaging won’t change this.  But again, not your point.  <br>
<br>
> I don't like the current draft very much. In particular, I am very dissatisfied with the huge cost of providing null safety only for primitive types.<br>
<br>
The second sentence is the best part of your mail, pointing out that we’re incurring a lot of complexity whose benefit only accrues to some of the types.  This is indeed suboptimal. <br>
<br>
> Now I have an idea: it's time to provide generic non null types for Java.<br>
<br>
You say this like it is a new idea!  We have explored this in *literally every iteration of Valhalla.*. At each iteration, we have asked ourselves whether the key distinctions could be replaced by general-purpose “emotional” (bang and question) type operators, or whether even that notation is helpful or harmful to user intuition. At each point, the answer has been “almost, but not quite.”  And in each iteration, we’ve continued to chip away at the difference, and ask ourselves the question again.  The current iteration is still a “no”, but it is still a matter of active exploration, because *of course* Java developers would prefer this to the current val/ref scheme.  (Or at least some of them think they would.). <br>
<br>
> Since the universal generics draft has decided to break compatibility, we can go further<br>
<br>
I don’t know what you mean by “decided to break compatibility”, but even if that were true (and yes, there are small incompatibilities, such as “what happens when you lock on Integer”), the rest would not remotely follow.  <br>
<br>
>  and provide universal non null types in Java, just like Kotlin.<br>
<br>
<br>
Haha, “just”.  No.  Even if we were to find our way to non-null types, it would not be “just” like anything.  <br>
<br>
> If we do, we no longer need the primitive class. It is enough to mark the value class as non null.<br>
<br>
Actually, no.  This is not the only difference between primitives and references.  If it were, we would have adopted this “solution” a long time ago.  <br>
<br>
As I said, there’s a lot of good thoughts in here, and the relationship between values and non-rulllable types has been a constant question along this journey, and still is.  We may be getting closer to having these concepts meet up.  But it is not “just” anything.  Stay tuned.</blockquote></div>