Alternative to IdentityObject & ValueObject interfaces

Brian Goetz brian.goetz at oracle.com
Thu Mar 24 12:46:44 UTC 2022



On 3/23/2022 10:51 PM, Dan Smith wrote:
>> On Mar 22, 2022, at 5:56 PM, Dan Smith <daniel.smith at oracle.com> wrote:
>>
>> - Variable types: I don't see a good way to get the equivalent of an 
>> 'IdentityObject' type. It would involve tracking the 'identity' 
>> property through the whole type system, which seems like a huge 
>> burden for the occasional "I'm not sure you can lock on that" error 
>> message. So we'd probably need to be okay letting that go. 
>> Fortunately, I'm not sure it's a great loss—lots of code today seems 
>> happy using 'Object' when it means, informally, "object that I've 
>> created for the sole purpose of locking".
>>
>> - Type variable bounds: this one seems more achievable, by using the 
>> 'value' and 'identity' keywords to indicate a new kind of bounds 
>> check ('<identity T extends Runnable>'). Again, it's added 
>> complexity, but it's more localized. We should think more about the 
>> use cases, and decide if it passes the cost/benefit analysis. If not, 
>> nothing else depends on this, so it could be dropped. (Or left to a 
>> future, more general feature?)
>
> Per today's discussion, this part seems to be the central question: 
> how much value can we expect to get out of compile-time checking?

This is indeed the question.  There's both a "theory" and a "practice" 
aspect, too.

> The type system is going to have three kinds of types:
> - types that guarantee identity objects
> - types that guarantee value objects
> - types that include both kinds of objects
>
> That third kind are a problem: we can specify checks with false 
> positives (programmer knows the operation is safe, compiler complains 
> anyway) or false negatives (operation isn't safe, but the compiler 
> lets it go).

Flowing {Value,Identity}Object property is likely to require shoring up 
intersection types too, since we can express Runnable&IdentityObject as 
a type bound, but not as a denotable type.  Var helps a little here but 
ultimately this is a hole through which information will drain.

The arguments you make here are compelling to me, that while it might 
work in theory, in practice there are too many holes:

  - Legacy code that already deals in Object / interfaces and is not 
going to change
  - Even in new code, I suspect people will continue to do so, because 
as you say, it is tedious for marginal value
  - The lack of intersection types will make it worse
  - Because of the above, many of the errors would be more like 
warnings, making it even weaker

All of this sounds like a recipe for "new complexity that almost no one 
will actually use."



More information about the valhalla-spec-observers mailing list