On Thu, May 26, 2022 at 1:34 PM Kevin Bourrillion <kev...@google.com> wrote: > > I'd like to bump this thread, as it seems to me to be the biggest obstacle to > bucket 2 being able to deliver value. > > * A warning not just on synchronization, but on *any* identity-dependence.
This will have high costs in the regular performance model as it will require additional checks in the implementation of the if_acmp bytecode (which today is basically a pointer comparison) and in Object::hashcode(). I'm not convinced the community would welcome a performance regression here to gain the warning. > * Not special for Integer etc.; it all needs to work through a general > facility that anyone can use. > * We don't need the constructor warnings, though. > * The annotation should evoke the idea of "this class is becoming a bucket 2 > class". > * It would be vestigial once the class *is* bucket-2. > * I would lean against enshrining the "value-based" terminology even > further (we can get into this if necessary). > * I think we need an explicit way to clearly and *intentionally* depend on > identity. This code would *prefer to break* if the objects in use became > bucket-2. e.g.: > * o1.identity() == o2.identity() // I like this > * System.identity(o1) == System.identity(o2) // this too > * System.identityEquals(o1, o2) > * o1 === o2 Are these marker methods? What would they return? Does this implementation meet the requirements of what you're envisioning here? Object identity(Object o) { if (o.isValue()) { throw new IAE(); } return o; } --Dan > > Thoughts? > > > On Tue, Apr 26, 2022 at 3:09 PM Kevin Bourrillion <kev...@google.com> wrote: >> >> Above, when I said the proposed `==` behavior is "not a behavior that anyone >> ever *actually wants* -- unless they just happen to have no fields of >> reference types at all", I did leave out some other cases. Like when your >> only field types (recursing down fields of value types) that are reference >> types are types that don't override `equals()` (e.g. `Function`). In a way >> this sort of furthers my argument that the boundary between when `==` is >> safely an `equals` synonym and when it isn't is going to be difficult to >> perceive. Yet, since people hunger for `==` to really mean `equals`, they >> are highly overwhelmingly likely to do it as much as possible whenever they >> are convinced it looks safe. And then one addition of a string field in some >> leaf-level type can break a whole lot of code. >> >> >> On Tue, Apr 26, 2022 at 2:53 PM Dan Smith <daniel.sm...@oracle.com> wrote: >> >>> Yes, a public annotation was the original proposal. At some point we scaled >>> that back to just JDK-internal. The discussions were a long time ago, but >>> if I remember right the main concern was that a formalized, Java SE notion >>> of "value-based class" would lead to some unwanted complexity when we >>> eventually get to *real* value classes (e.g., a misguided CS 101 course >>> question: "what's the difference between a value-based class and a value >>> class? which one should you use?"). >> >> >> Yeah, I hear that. The word "value" does have multiple confusable meanings. >> I'd say the key difference is that "value semantics" are logically a >> *recursive* rejection of identity, while a Valhalla B2/B3 class on its own >> addresses only one level deep. >> >> Anyway, I think what I'm proposing avoids trouble by specifically labeling >> one state as simply the transitional state to the other. I'm not sure >> there'd be much to get hung up on. >> >> >>> >>> It seemed like producing some special warnings for JDK classes would >>> address the bulk of the problem without needing to fall into this trap. >> >> >> I'd just say it addresses a more specific problem: how *those* particular >> classes can become B2/B3 (non-identity) classes. >> >> >>> >>> Would an acceptable compromise be for a third-party tool to support its own >>> annotations, while also recognizing @jdk.internal.ValueBased as an >>> alternative spelling of the same thing? >> >> >> I think it's "a" compromise :-), I will just have to work through how >> acceptable. >> >> Is there any such thing as a set of criteria for when a warning deserves to >> be handled by javac instead of left to all the world's aftermarket static >> analyzers to handle? >> >>> (Secondarily... why are we warning only on synchronization, and not on `==` >>> or (marginal) `identityHC`?) >>> >>> I think this was simply not a battle that we wanted to fight—discouraging >>> all uses of '==' on type Integer, for example. >> >> >> Who would be fighting the other side of that battle? Not anyone having some >> need to use `==` over `.equals()`, because we'll be breaking them when >> Integer changes buckets anyway. So... just the users saying "we should get >> to use `==` as a shortcut for `.equals()` as long as we stay within the >> cached range"? Oh, wait: >> >> >>> Within these constraints, there are reasonable things that can be done with >>> '==', like optimizing for a situation where 'equals' is likely to be true. >> >> >> Ok, that too. Fair I suppose... it's just that it's such a very special >> case... >> >> -- >> Kevin Bourrillion | Java Librarian | Google, Inc. | kev...@google.com > > > > -- > Kevin Bourrillion | Java Librarian | Google, Inc. | kev...@google.com