----- Original Message ----- > From: "Maurizio Cimadamore" <maurizio.cimadam...@oracle.com> > To: "daniel smith" <daniel.sm...@oracle.com>, "valhalla-spec-experts" > <valhalla-spec-experts@openjdk.java.net> > Sent: Wednesday, March 23, 2022 11:23:26 AM > Subject: Re: Alternative to IdentityObject & ValueObject interfaces
> On 22/03/2022 23:56, Dan Smith wrote: >> Other abstract classes and interfaces are fine being neither (thus supporting >> both kinds of subclasses). > > I feel that for such a proposal to be really useful (but that's true for > the interface-based approach as well IMHO), you need a way for the _use > site_ to attach an identity vs. value annotation to types that can > feature both polarities (Object, interfaces, value-compatible abstract > classes). > > It's perfectly fine to have identity vs. non-identity as a declaration > property, for the cases whether that works. E.g. an ArrayList instance > will always have identity. An instance of a `value class Point` will > always be identity-less. Using modifiers vs. marker interfaces here is > mostly an isomorphic move (and I agree that adding modifiers has less > impact w.r.t. compatibility). > > But it feels like both interfaces and decl-site modifiers fall short of > having a consistent story for the "neither" case. I feel we'd like > programmers to be able to say things like: > > ``` > class Foo { > identity Object lock; > > void runAction(identity Runnable action) { ... } > } > ``` > > So, I believe the modifier idea has better potential than marker > interfaces, because it scales at the use site in ways that marker > interfaces can't (unless we allow intersection types in declarations). > But of course I get that adding a new use-site modifier (like `final`) > is also not to be taken lightly; aside from grammar conundrums, as you > say it will have to be tracked by the type system. > > Stepping back, you list 4 use cases: > >> - Dynamic detection >> >> - Subclass restriction >> >> - Variable types >> >> - Type variable bounds > IMHO, they are not equally important. And once you give up on "variable > types" (as explained above, I believe this use case is not adequately > covered by any proposal I've seen), then there's a question of how much > incremental value the other use cases add. Dynamic detection can be > added cheaply, fine. I also think that, especially in the context of > universal generics, we do need a way to say: "this type variable is > legacy/identity only" - but that can also be done quite cheaply. IMHO, > restricting subclasses doesn't buy much, if you then don't have an > adequate way to restrict type declarations at the use sites (for those > things that cannot be restricted at the declaration), so I'd be also > tempted to leave that use case alone as YAGNI (by teaching developers > that synchronizing on Object and interface types is wrong, as we've been > already trying to do). > > P.S. > > While writing this, a question came up: let's say I have a generic class > like this: > > ``` > class IdentityBox<identity T> { ... } > ``` > > Is IdentityBox<Runnable> a well-formed parameterized type? Based on your > description I'm not sure: Runnable has the "neither" polarity, but T > expects "identity". With marker interfaces this will just not work. With > modifiers we could perhaps allow with unchecked warning? > > I think it's important that the above type remains legal: I'd expect > users to mark their type-variables as "identity" in cases where they > just can't migrate the class implementation to support universal type > variables. But if that decision results in a source incompatible change > (w.r.t. existing parameterizations such as IdentityBox<Runnable>), then > it doesn't look like a great story migration-wise. Yes ! The neither types (Object, interfaces, abstract classes) act as an eraser of the identity|value bit if we do not support use site identity|value modifier, something like IdentityBox<identity Runnable>. And given that there is already existing codes in the wild that does not specify "identity" or "value" we need a kind of unsafe conversion/unsafe warning between the new world with use site type annotation and the old world with no type annotation. As Brian said to Kevin, it's a problem very similar to the introduction of a null type annotation, it will be painful. > > Maurizio Rémi