From daniel.smith at oracle.com Tue Jan 5 19:11:07 2021 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 5 Jan 2021 12:11:07 -0700 Subject: PrimitiveObject interface Message-ID: <830103D4-935F-4EDF-AED9-A4579E0A0CD1@oracle.com> A design change I'd like to propose: in addition to the IdentityObject interface, let's have a complementary PrimitiveObject interface. Like IdentityObject, the PrimitiveObject interface can be extended/implemented explicitly or, sometimes, implicitly. Some language rules: - Every primitive class implicitly implements PrimitiveObject (this is new) - Every non-primitive concrete class implicitly implements IdentityObject (this is not new) - Certain abstract classes (e.g., those with fields) implicitly implement IdentityObject (this is not new) - All other abstract classes, interfaces, and Object implement neither interface by default - Arrays implement IdentityObject - It's an error for a class or interface to extend both interfaces (extending neither, if you're an interface or abstract class, is fine) This leaves us with every object implementing exactly one of those two interfaces. We've wondered whether there are use cases to justify the second interface. Having gained some experience in this system, I think it's safe to say there will be. For example, an abstract class or interface extended by a family of primitive classes may wish to explicitly implement PrimitiveObject as a way to communicate a particular performance model, immutability, etc., to clients. Or certain primitive-like features, like operator overloading, may interact with libraries through type variables that extend PrimitiveObject. I also like the symmetry, which avoids any biasing of one side over the other. Revised JVM behavior: - Primitive classes either get PrimitiveObject as an injected superinterface or reject classes without that superinterface. (Which one? TBD.) - Non-primitive concrete classes get IdentityObject as an injected superinterface. (Not possible to just reject classes here, due to legacy class files.) - Abstract classes may be declared to support primitive subclasses (this is a separate mechanism). If an abstract class does not opt in to primitive subclasses, it gets IdentityObject as an injected superinterface. - Arrays have IdentityObject as a supertype - It's a (load-time?) error for a class or interface to extend both PrimitiveObject and IdentityObject From mcnepp02 at googlemail.com Wed Jan 6 11:46:00 2021 From: mcnepp02 at googlemail.com (Gernot Neppert) Date: Wed, 6 Jan 2021 12:46:00 +0100 Subject: PrimitiveObject interface Message-ID: <6ad3f7f2-dd61-2416-c535-fdef81ce1b01@gmail.com> Hi Dan, a while ago on this mailing list, there already was a discussion about the necessity of two complementary interfaces. IIRC, consent was obtained that, since "IdentityObject" actually adds some capabilities to java.lang.Object - such as synchronization - a marker interface was warranted, whereas primitive classes do not offer anything over plain java.lang.Object which could be exploited via an explicit interface. Nevertheless, back to your propsal: I dare challenge your assertion about "symmetry". If we had such an interface "PrimitiveObject" - in what contexts would that appear? As you yourself wrote, it could by used as type-bounds for method arguments. Now, consider a generic method void foo(T arg) { } Once I pass an argument of a concrete primitive type to this method, it will be automatically submitted to the "reference-projection", since the argument is of an interface-type. Question 1: is this even possible? I may have gotten this wrong, but to me the "reference-projection" implies that an object of the associated ".ref" class will be passed, which would then not implement "PrimitiveObject" in the first place! Question 2: the erased function "foo" has an argument of an interface-type, which is a good old-fashioned Java reference. Inside foo(), in what way would I be able to exploit the fact that arg was a primitve object originally? Some further remarks: > Certain abstract classes (e.g., those with fields) implicitly implement IdentityObject (this is not new) What would happen if such an abstract class explicitly implements PrimitiveObject? Would the compiler be required to reject compilation? > It's a (load-time?) error for a class or interface to extend both PrimitiveObject and IdentityObject Would that be necessary? Given that a conforming compiler could never generate such a class, what potential danger would be averted by introducing such a load-time check? From daniel.smith at oracle.com Wed Jan 6 16:41:18 2021 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 6 Jan 2021 09:41:18 -0700 Subject: PrimitiveObject interface In-Reply-To: <6ad3f7f2-dd61-2416-c535-fdef81ce1b01@gmail.com> References: <6ad3f7f2-dd61-2416-c535-fdef81ce1b01@gmail.com> Message-ID: <80505A73-AF52-470D-B3E5-816F6B288325@oracle.com> Replies to some helpful feedback on the observers list: > On Jan 6, 2021, at 4:46 AM, Gernot Neppert wrote: > > Hi Dan, > > a while ago on this mailing list, there already was a discussion about the necessity of two complementary interfaces. > > IIRC, consent was obtained that, since "IdentityObject" actually adds some capabilities to java.lang.Object - such as synchronization - a marker interface was warranted, > > whereas primitive classes do not offer anything over plain java.lang.Object which could be exploited via an explicit interface. Yes, that was our thinking at one point. But we've since begun to think that a positive assertion about being a primitive object has merit as well. "Values *might* be primitive objects" and "values *will* be primitive objects" are two different things. While the same set of operations is supported in either case, the latter guarantees certain properties that the former does not. That said, I wouldn't expect PrimitiveObject to be used often, because the properties it guarantees are fairly subtle and not relevant to most applications. > Nevertheless, back to your propsal: > > I dare challenge your assertion about "symmetry". If we had such an interface "PrimitiveObject" - in what contexts would that appear? > > As you yourself wrote, it could by used as type-bounds for method arguments. Now, consider a generic method > > void foo(T arg) { > > } > > Once I pass an argument of a concrete primitive type to this method, it will be automatically submitted to the "reference-projection", since the argument is of an interface-type. > > Question 1: is this even possible? I may have gotten this wrong, but to me the "reference-projection" implies that an object of the associated ".ref" class will be passed, which would then not implement "PrimitiveObject" in the first place! There is only one object. There are times when the language operates on the object itself, and times when it operates on a *reference to* the object. Reference types are used when working with references. PrimitiveObject is a reference type. A variable with type PrimitiveObject stores a reference to an instance of a primitive class. As generics are currently defined, a type argument must be a reference type that is a subtype of the bound; a type like Point.ref satisfies these constraints for 'T extends PrimitiveObject'. (We'll also be pursuing enhancements to generics to eliminate that reference type constraint, so that primitive value types like Point are acceptable type arguments, too.) > Question 2: the erased function "foo" has an argument of an interface-type, which is a good old-fashioned Java reference. Inside foo(), in what way would I be able to exploit the fact that arg was a primitve object originally? It still *is* a primitive object. It happens to be passed by reference. What do you know about a PrimitiveObject? Things like: - Its state is all final (though field values may themselves be mutable) - Its '==' operation will be of the "heavier" variety - Certain JVM optimizations related to escape analysis will have the opportunity to be applied - Reflective operations will have certain behaviors, e.g. getClass has a default instance Like I said, this list isn't particularly useful in most contexts, but I also think the bar is low enough here that it's enough to justify a complementary interface to IdentityObject. > Some further remarks: > >> Certain abstract classes (e.g., those with fields) implicitly implement IdentityObject (this is not new) > > What would happen if such an abstract class explicitly implements PrimitiveObject? Would the compiler be required to reject compilation? Yep. It's an error to implement both interfaces. >> It's a (load-time?) error for a class or interface to extend both PrimitiveObject and IdentityObject > > Would that be necessary? Given that a conforming compiler could never generate such a class, what potential danger would be averted by introducing such a load-time check? A non-conforming compiler can generate such classes, and we want strong guarantees about run-time behavior. From daniel.smith at oracle.com Wed Jan 13 05:40:43 2021 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 12 Jan 2021 22:40:43 -0700 Subject: EG meeting, 2021-01-13 Message-ID: <547C76AA-5F2B-4819-AE4B-81FE74A55039@oracle.com> The next EG Zoom meeting is Wednesday at 4pm UTC (9am PST, 12pm EST). We can discuss the mail "PrimitiveObject interface", in which I propose a second interface to complement IdentityObject. See you then! From daniel.smith at oracle.com Wed Jan 13 06:11:10 2021 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 12 Jan 2021 23:11:10 -0700 Subject: EG meeting, 2021-01-13 In-Reply-To: <547C76AA-5F2B-4819-AE4B-81FE74A55039@oracle.com> References: <547C76AA-5F2B-4819-AE4B-81FE74A55039@oracle.com> Message-ID: > On Jan 12, 2021, at 10:40 PM, Dan Smith wrote: > > The next EG Zoom meeting is Wednesday at 4pm UTC (9am PST, 12pm EST). Err, make that 5pm UTC. Copy/paste fail. From daniel.smith at oracle.com Wed Jan 13 17:46:51 2021 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 13 Jan 2021 10:46:51 -0700 Subject: PrimitiveObject interface In-Reply-To: <830103D4-935F-4EDF-AED9-A4579E0A0CD1@oracle.com> References: <830103D4-935F-4EDF-AED9-A4579E0A0CD1@oracle.com> Message-ID: A couple of notes from the EG meeting discussion. > On Jan 5, 2021, at 12:11 PM, Dan Smith wrote: > > We've wondered whether there are use cases to justify the second interface. Having gained some experience in this system, I think it's safe to say there will be. For example, an abstract class or interface extended by a family of primitive classes may wish to explicitly implement PrimitiveObject as a way to communicate a particular performance model, immutability, etc., to clients. Or certain primitive-like features, like operator overloading, may interact with libraries through type variables that extend PrimitiveObject. I also like the symmetry, which avoids any biasing of one side over the other. Consensus that these use cases/arguments aren't strong enough to justify any major costs, but also as a nice-to-have, the costs don't seem very large. So, worth doing. > Revised JVM behavior: > - Primitive classes either get PrimitiveObject as an injected superinterface or reject classes without that superinterface. (Which one? TBD.) Dan Heidinga expressed a preference for validation rather than injection, arguing that it's always simpler to validate. Fred Parain expressed a preference for injection, for uniformity with the treatment of IdentityObject. I guess that leaves us at TBD?maybe something we can check in on again when we've done some implementation. From daniel.smith at oracle.com Wed Jan 13 17:54:42 2021 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 13 Jan 2021 10:54:42 -0700 Subject: Valhalla Zoom week in March 2021 Message-ID: Tentative dates for a Valhalla Zoom meetup to get everyone in sync, solidify design choices, and make plans for feature completion: March 15-18 or March 22-25 Something like 3-4 hours per day, within the 7a-12a PDT / 3p-8p CET window. (Time zones are 1 hour closer together for these two weeks!) I've heard one vote against March 15-18. If anybody else has conflicts, let me know! Also happy to hear suggestions on how to make the best use of our time. From daniel.smith at oracle.com Wed Jan 27 06:27:30 2021 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 26 Jan 2021 23:27:30 -0700 Subject: EG meeting *canceled*, 2021-01-27 Message-ID: <6DE2F9FD-97C8-4C76-A880-0396D0A00BF6@oracle.com> Nothing new on the mailing list, we'll cancel this one. Next meeting February 10.