> From: "daniel smith" <daniel.sm...@oracle.com>
> To: "Remi Forax" <fo...@univ-mlv.fr>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts@openjdk.java.net>
> Sent: Wednesday, January 26, 2022 4:42:30 PM
> Subject: Re: The interfaces IdentityObject and ValueObject must die !

>> On Jan 26, 2022, at 2:18 AM, [ mailto:fo...@univ-mlv.fr |
>> fo...@univ-mlv.fr ] wrote:

>>> In other words: I don't see a use case for distinguishing between primitive 
>>> and
>>> value classes with different interfaces.

>> Primitive classes does not allow nulls and are tearable, following your 
>> logic,
>> there should be a subclass of ValueObject named PrimitiveObject that reflects
>> that semantics.

> But this isn't a property of the *class*, it's a property of the *type*, as 
> used
> at a particular use site. If you want to know whether an array is flattened,
> the class of the component can't tell you.

The semantics B1/B2/B3 is a property of the class, an instance of a value class 
stored in an Object is still an instance of a value class, same for primtive 
classes. 

Being flattenable or not, is an orthogonal concern. Being flattenable for a 
field or a local variable/parameter it's a property of the descriptor, but for 
arrays it's a property of the array class because arrays are covariant in Java. 

For arrays, a code like this should work 
Object[] o = new QComplex;[3]; 
o[1] = QComplex;.new(...); 

>> This is especially useful when you have an array of PrimitiveObject, you know
>> that a storing null in an array of PrimitiveObject will always generate a NPE
>> at runtime and that you may have to use either the volatile semantics or a 
>> lock
>> when you read/write values from/to the array of PrimitiveObject.

>> For examples,
>> public void m(PrimitiveObject[] array, int index) {
>> array[index] = null; // can be a compile time error
>> }

> If we said

> primitive class Point implements PrimitiveObject

> then it would be the case that

> Point.ref[] <: PrimitiveObject[]

> and so PrimitiveObject[] wouldn't mean what you want it to mean.

> We could make a special rule that says primitive types are subtypes of a 
> special
> interface, even though their class does not implement that interface. But that
> doesn't really work, either—primitive types are monomorphic. If you've got a
> variable with an interface type, you've got a reference.

I don't understand why you want Point.ref/LPoint; to be a PrimitiveObject and 
not a ValueObject. 
We have QPoint;[] <: LPoint;[] so LPoint; implements ValueObject and QPoint; 
implements PrimitiveObject. 

Anyway, it shows that using interfaces to represent properties of a class 
(behavior of ==, synchronized, nullability, tearability) is far from obvious. 

> Meanwhile, I'd suggest writing the method like this, using universal generics:

> <T> public void m(T[] array, int index) {
> array[index] = null; // null warning
> }

If you are Okay with code that can raise a NPE, why are you not Okay with code 
that can raise an IllegalMonitorStateException ? 
Or said differently why ValueObject and not PrimitiveObject. 

I'm not advocating for having 3 interfaces, because i think of the ratio 
cost/benefit of such interfaces is poor. But having 2 interfaces is 
definitively weird since we have updated the model to B1/B2/B3. 

>> An impossible type, it's a type that can be declared but no class will ever
>> match.

>> Examples of impossible types, at declaration site
>> interface I extends ValueObject {}
>> interface J extends IdentityObject {}
>> <T extends I & J> void foo() { }
> It would definitely be illegal to declare a class that extends I and J. Our
> rules about well-formedness for bounds have always been sketchy, but
> potentially that would be a malformed type variable.

another cost of introducing those interfaces, the JLS has to be updated to take 
care of the invalid bounds 

>>> Abandoning the property entirely would be a bigger deal.

>> If we do not use interfaces, the runtime class of java.lang.Object can be
>> Object, being an identity class or not is a just a bit in the reified class,
>> not a compile time property, there is contamination by inheritance.
> Object can't be an identity class, at compile time or run time, because some
> subclasses of Object are value classes.

Object the type is not an identity class, but Object the class (the Object in 
"new Object()") is an identity class. 

> What you'd need is a property of individual *objects*, not represented at all
> with the class. Theoretically possible, but like I said, a pretty big
> disruption to our current model.

nope, we need to decouple the notion of type from the notion of being an 
identity/value/primitive class because it's a property of the class not a 
property of the type. 

>> For me, it's like opening the door of your house to an elephant because it 
>> has a
>> nice hat and saying you will fix that with scotch-tape each time it touches
>> something.

> Ha. This sounds like maybe there's a French idiom involved, but anyway we 
> should
> try to get John to add this to his repertoire of analogies.

"Like a bull in a china shop" is "comme un éléphant dans un magazin de 
porcelaine" in French. 

Rémi 

Reply via email to