From daniel.smith at oracle.com Wed Sep 2 22:08:18 2020 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 2 Sep 2020 16:08:18 -0600 Subject: Re-interpreting 'new Object()' Message-ID: <3BC8F4F5-BEC1-466D-A55D-748F3CAE6E59@oracle.com> Followup of discussion in last week's meeting: how does 'new Object()' interact with the IdentityObject interface? I've been able to get the story down to a few concrete changes that feel manageable. --- API changes - Add a java.lang.IdentityObject interface. The interface has no members (don't want to disrupt method resolution, etc., in any way). The javadoc, for information purposes, describes the behaviors of various Object methods. - Add a public java.lang.SimpleIdentityObject class (I'm happy to entertain alternative names). The class has a default constructor, no members, and is 'final'. It will implicitly implement IdentityObject. The javadoc describes how it can be used as a general-purpose lock or sentinel. - (Optionally) Add a static 'newIdentity()' method to Object, implemented as 'return new SimpleIdentityObject()'. Return type TBD. (Caution: we've never added a method to Object before. If anyone else has used that name anywhere, it will conflict. May also cause surprising reflection results from, e.g., 'getMethods'.) - (Optionally) Make Object 'abstract'. --- Language changes - The expressions 'new Object()' and 'Object::new' trigger a warning. ("Use 'Object.newIdentity' or 'new SimpleIdentityObject' instead.") - If Object has been made abstract, 'new Object()' and 'Object::new' are exempt from the abstract class error check. - (Optionally) In a future iteration of the language, 'new Object()' and 'Object::new' are errors (perhaps by removing the abstract class exemption). --- JVM changes - At runtime, the instruction 'new java/lang/Object' behaves as if it were 'new java/lang/SimpleIdentityObject'. Note that, for this reason, SimpleIdentityObject needs a well-defined, specified name. (Although we don't necessarily have to perform access control...) - If Object has been made abstract, the instruction 'new java/lang/Object' does not perform the link-time check for an abstract class. (The 'invokespecial Object.()V' instruction is unchanged. It continues to invoke the Object constructor. Verification allows it, even though the object on the stack may be an uninitialized SimpleIdentityObject, because the 'new' instruction names 'java/lang/Object'. This may violate some assumptions about initialization method execution, but is sound because SimpleIdentityObject doesn't need to do any initialization.) I'm not sure we'll ever be able to deprecate 'new java/lang/Object' in the JVM, but I suppose it's possible, with some disruption, for version X.0+ classes. JVMs will still need to support older class files. --- Bonus discussion: Here's an alternative story, if we wanted to pursue a particular kind of factory methods in the language: - Classes, including abstract classes and interfaces, can declare a static method named 'new', returning the class's type. (Syntax subject to bikeshedding.) - 'new ClassName' can be used to invoke these methods as if they were constructors, without the usual hostility to abstract classes and interfaces. Invocations compile to 'invokestatic'. - The Object class is updated to be abstract but provide one of these factories. There is no 'newIdentity' method. - The above language changes don't apply. - The above JVM changes are still needed. (We still have legacy 'new java/lang/Object' code.) From daniel.smith at oracle.com Wed Sep 2 23:30:17 2020 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 2 Sep 2020 17:30:17 -0600 Subject: IdentityObject & abstract superclasses In-Reply-To: <2B1E2C32-C23B-40FD-937B-ED8B09C0258C@oracle.com> References: <2B1E2C32-C23B-40FD-937B-ED8B09C0258C@oracle.com> Message-ID: Summarizing, here's what I think we want: --- Language features java.lang.IdentityObject is a normal interface, can be implemented/extended by any class or interface. A non-inline class with any of the following properties implicitly implements IdentityObject: - Is concrete (java.lang.Object excluded) - Declares a (possibly private) instance field - Is an inner class with an enclosing instance - Declares an instance initializer - Lacks a no-arg constructor (explicit or implicit) - Declares a no-arg constructor with a non-empty body (something other than 'super();') - Declares a synchronized method A warning encourages classes in the last four categories to explicitly implement IdentityObject in order to ensure stable class evolution. (Possibly of the "this will become an error in a future release" variety.) (Note that I'm tentatively allowing constructor overloading in a non-IdentityObject class. It's not generally useful, but is harmless and could be useful in some special circumstances.) It is a compile-time error if (among other things) an inline class: - Implements IdentityObject, directly or indirectly - Can't access its superclass's no-arg constructor - Declares a synchronized method --- JVM features Traditionally, a class declares that it supports identity subclasses by declaring one or more methods. (Because with no method, it's impossible to initialize a subclass instance.) Similarly, a class declares that it supports inline subclasses by declaring an method whose ACC_ABSTRACT flag is set. Invocations of that method are no-ops. (Tentatively. We could encode this differently. The important metadata is i) the class supports inline subclasses, and ii) access flags for inline subclasses.) A class that is not inline and does not declare support for inline subclasses implicitly implements IdentityObject. A class that declares support for inline subclasses is subject to the following constraints at class load time: - Must be ACC_ABSTRACT (java.lang.Object excluded) - Must not declare an instance field - Must not declare a synchronized method - Must not implement IdentityObject, directly or indirectly - Must have access to extend the superclass (per the super's abstract method) An inline class is subject to similar constraints at class load time: - Must not be ACC_ABSTRACT and must be ACC_FINAL - All fields must be ACC_FINAL - Must not declare a synchronized method - Must not implement IdentityObject, directly or indirectly - Must have access to extend the superclass (per the super's abstract method) --- API features (Optionally) The method Class.Interfaces(), and similar reflection API points, filters out IdentityObject when it is not explicitly named in the class file. From peter.levart at gmail.com Thu Sep 3 07:03:24 2020 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 3 Sep 2020 09:03:24 +0200 Subject: IdentityObject & abstract superclasses In-Reply-To: References: <2B1E2C32-C23B-40FD-937B-ED8B09C0258C@oracle.com> Message-ID: <6af21ac7-ee66-c75b-e3b3-e2de01e85e23@gmail.com> On 9/3/20 1:30 AM, Dan Smith wrote: > (Optionally) The method Class.Interfaces(), and similar reflection API points, filters out IdentityObject when it is not explicitly named in the class file. While this might sound ok from standpoint of not disturbing existing code that uses reflection, it is not consistent with other methods in the reflection API and language itself. For example, if (o instanceof IdentityObject) evaluates to true, but o.getClass().getInterfaces() does not contain IdentityObject.class, then this means more trouble than it is worth. Reflection API has always been more about modeling runtime representation than explicit source-level language constructs. Class.getDeclaredConstructors() for example returns implicit default constructor that has not been explicitly declared, Constructor.getParameterTypes() includes the type of implicit outer instance parameter in inner classes, etc... The difference here is that all existing implicit constructs are generated by javac and are explicitly present in the class file. IdentityObject OTOH is to be added by VM in case it does not exist in class file (only for class files compiled for target < X.0, because for target >= X.0, javac would already take care of that either by adding the interface implicitly to class file or forcing user to add it to source). But from user standpoint it does not matter because user only sees Java source code on one side and the program behavior on the other side. (s)he very rarely looks into bytecodes/classfile. (s)he would also be surprised to find reflection behavior change depending on whether some source was compiled for target < X.0 vs. target >= X.0 ... Regards, Peter From peter.levart at gmail.com Thu Sep 3 07:17:25 2020 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 3 Sep 2020 09:17:25 +0200 Subject: IdentityObject & abstract superclasses In-Reply-To: <6af21ac7-ee66-c75b-e3b3-e2de01e85e23@gmail.com> References: <2B1E2C32-C23B-40FD-937B-ED8B09C0258C@oracle.com> <6af21ac7-ee66-c75b-e3b3-e2de01e85e23@gmail.com> Message-ID: On 9/3/20 9:03 AM, Peter Levart wrote: > For example, if (o instanceof IdentityObject) evaluates to true, but > o.getClass().getInterfaces() does not contain IdentityObject.class, ...well, this is not the right comparison as the 1st test looks for IdentityObject implemented anywhere in the type hierarchy of o's runtime class while the 2nd expression only looks for interfaces declared by the runtime class itself. But anyway, it would be surprising to find VM claim that some class implements IdentityObject (for example by throwing a runtime error at linkage attempt with some inline subclass) and at the same time omit IdentityObject from Class.getInterfaces()... Peter From brian.goetz at oracle.com Thu Sep 3 14:12:43 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 3 Sep 2020 10:12:43 -0400 Subject: Re-interpreting 'new Object()' In-Reply-To: <3BC8F4F5-BEC1-466D-A55D-748F3CAE6E59@oracle.com> References: <3BC8F4F5-BEC1-466D-A55D-748F3CAE6E59@oracle.com> Message-ID: <5feac43a-ded7-36e8-7cb9-45beef2f3207@oracle.com> This sounds mostly in line with what I was expecting.? Some minor comments inline. > API changes > > - Add a java.lang.IdentityObject interface. The interface has no members (don't want to disrupt method resolution, etc., in any way). The javadoc, for information purposes, describes the behaviors of various Object methods. It's a shame this isn't the home for identityHashCode, but oh well. > - Add a public java.lang.SimpleIdentityObject class (I'm happy to entertain alternative names). The class has a default constructor, no members, and is 'final'. It will implicitly implement IdentityObject. The javadoc describes how it can be used as a general-purpose lock or sentinel. An almost-attractive bikeshed color here is a nested (static final) class -- Object.Identity.? This means you say ??? new Object.Identity() when you want ... a new object identity and nothing else. Except ... this class is inherited ... grr.?? I have always wished static nested classes were not inherited. In the absence of that, calling it ObjectIdentity would suffice: ??? Object lock = new ObjectIdnetity() > - (Optionally) Add a static 'newIdentity()' method to Object, implemented as 'return new SimpleIdentityObject()'. Return type TBD. (Caution: we've never added a method to Object before. If anyone else has used that name anywhere, it will conflict. May also cause surprising reflection results from, e.g., 'getMethods'.) If we had a nested class, the method would not really be needed, since the primary purpose of the method would be discoverability. > - (Optionally) Make Object 'abstract'. I think there's a pile of things we can do later to finish the job, and this could be in it. > - (Optionally) In a future iteration of the language, 'new Object()' and 'Object::new' are errors (perhaps by removing the abstract class exemption). Also in the pile of "for later". > --- > > Bonus discussion: Here's an alternative story, if we wanted to pursue a particular kind of factory methods in the language: > > - Classes, including abstract classes and interfaces, can declare a static method named 'new', returning the class's type. (Syntax subject to bikeshedding.) > > - 'new ClassName' can be used to invoke these methods as if they were constructors, without the usual hostility to abstract classes and interfaces. Invocations compile to 'invokestatic'. > > - The Object class is updated to be abstract but provide one of these factories. There is no 'newIdentity' method. > > - The above language changes don't apply. > > - The above JVM changes are still needed. (We still have legacy 'new java/lang/Object' code.) > This idea has come up in almost this exact form before (several times) in different contexts.? FWIW, each time, it seems initially attractive, and then after some thought, doesn't seem to deliver the punch one might hope.? (You could think of this as an limited form of operator overloading.) A big drawback has always been that it throws a treasured invariant under the bus: `new Foo()` always returns a unique, unaliased, non-null reference.?? Lots of existing code subtly depends on this, as do many optimizations and security analyses.?? (Though, inline classes already do some of that damage, at least in part.) But my sense is that this is yet another place where it is a bigger hammer, with more costs, than is needed to solve this problem.? And I'm not sure users are better served by muddying what `new` means for the sake of not changing the relatively infrequent "I need a new idnetity" invocations. From brian.goetz at oracle.com Thu Sep 3 14:37:09 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 3 Sep 2020 10:37:09 -0400 Subject: IdentityObject & abstract superclasses In-Reply-To: References: <2B1E2C32-C23B-40FD-937B-ED8B09C0258C@oracle.com> Message-ID: The "lacks a no-arg ctor" is new and interesting.? I think what you're saying is that having an explicit no-arg ctor with an empty body is a more stable signal of intent than an implicit one?? I can see that. Shouldn't the non-empty body one be "declares any constructor with a non-empty body", regardless of arity?? The only reasonable thing here would be a side-effect (like an instance initializer) or a nontrivial super call, both of which seem to put you in the Identity category. Still not sold on keying off the existence of a constructor with a novel shape at the classfile level.? Seems too clever, and comes with a complex verification. On 9/2/2020 7:30 PM, Dan Smith wrote: > Summarizing, here's what I think we want: > > --- > Language features > > java.lang.IdentityObject is a normal interface, can be implemented/extended by any class or interface. > > A non-inline class with any of the following properties implicitly implements IdentityObject: > - Is concrete (java.lang.Object excluded) > - Declares a (possibly private) instance field > - Is an inner class with an enclosing instance > - Declares an instance initializer > - Lacks a no-arg constructor (explicit or implicit) > - Declares a no-arg constructor with a non-empty body (something other than 'super();') > - Declares a synchronized method > > A warning encourages classes in the last four categories to explicitly implement IdentityObject in order to ensure stable class evolution. (Possibly of the "this will become an error in a future release" variety.) > > (Note that I'm tentatively allowing constructor overloading in a non-IdentityObject class. It's not generally useful, but is harmless and could be useful in some special circumstances.) > > It is a compile-time error if (among other things) an inline class: > - Implements IdentityObject, directly or indirectly > - Can't access its superclass's no-arg constructor > - Declares a synchronized method > > --- > JVM features > > Traditionally, a class declares that it supports identity subclasses by declaring one or more methods. (Because with no method, it's impossible to initialize a subclass instance.) > > Similarly, a class declares that it supports inline subclasses by declaring an method whose ACC_ABSTRACT flag is set. Invocations of that method are no-ops. (Tentatively. We could encode this differently. The important metadata is i) the class supports inline subclasses, and ii) access flags for inline subclasses.) > > A class that is not inline and does not declare support for inline subclasses implicitly implements IdentityObject. > > A class that declares support for inline subclasses is subject to the following constraints at class load time: > - Must be ACC_ABSTRACT (java.lang.Object excluded) > - Must not declare an instance field > - Must not declare a synchronized method > - Must not implement IdentityObject, directly or indirectly > - Must have access to extend the superclass (per the super's abstract method) > > An inline class is subject to similar constraints at class load time: > - Must not be ACC_ABSTRACT and must be ACC_FINAL > - All fields must be ACC_FINAL > - Must not declare a synchronized method > - Must not implement IdentityObject, directly or indirectly > - Must have access to extend the superclass (per the super's abstract method) > > --- > API features > > (Optionally) The method Class.Interfaces(), and similar reflection API points, filters out IdentityObject when it is not explicitly named in the class file. > From daniel.smith at oracle.com Thu Sep 3 16:51:31 2020 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 3 Sep 2020 10:51:31 -0600 Subject: IdentityObject & abstract superclasses In-Reply-To: References: <2B1E2C32-C23B-40FD-937B-ED8B09C0258C@oracle.com> Message-ID: <7BC3F957-8589-421C-B3DC-5CDF3E0668F6@oracle.com> > On Sep 3, 2020, at 8:37 AM, Brian Goetz wrote: > > The "lacks a no-arg ctor" is new and interesting. I think what you're saying is that having an explicit no-arg ctor with an empty body is a more stable signal of intent than an implicit one? I can see that. > > Shouldn't the non-empty body one be "declares any constructor with a non-empty body", regardless of arity? The only reasonable thing here would be a side-effect (like an instance initializer) or a nontrivial super call, both of which seem to put you in the Identity category. The way I wrote these rules is confusing. Let me try again. An inline superclass must have a constructor of the form: Foo() { super(); } If this constructor is implicit (because the class body declares no constructors), that's fine. I guess we could force it to be explicit, but I think the goal here is to minimize the effort an abstract class puts into authorizing inline subclasses. Support for inline subclasses is the default behavior. If the 'super()' call in an empty no-arg constructor is implicit, that's fine. If the class body declares *other* constructors too, that's fine. When there are multiple paths to initialize an instance, the inline subclass will always choose the "do nothing" path. > Still not sold on keying off the existence of a constructor with a novel shape at the classfile level. Seems too clever, and comes with a complex verification. Yeah, I wonder if a straightforward "InlineSuperclass" attribute at the class level is a better way to encode this. John likes the idea that the class author explicitly says "there's no initialization to do", but I think it also works to specify that inline subclass creation uses a separate mechanism that simply doesn't perform initialization. From daniel.smith at oracle.com Thu Sep 3 17:02:51 2020 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 3 Sep 2020 11:02:51 -0600 Subject: Re-interpreting 'new Object()' In-Reply-To: <5feac43a-ded7-36e8-7cb9-45beef2f3207@oracle.com> References: <3BC8F4F5-BEC1-466D-A55D-748F3CAE6E59@oracle.com> <5feac43a-ded7-36e8-7cb9-45beef2f3207@oracle.com> Message-ID: <808F6B38-8FA9-43B3-AA20-C32121555A7A@oracle.com> > On Sep 3, 2020, at 8:12 AM, Brian Goetz wrote: > >> API changes >> >> - Add a java.lang.IdentityObject interface. The interface has no members (don't want to disrupt method resolution, etc., in any way). The javadoc, for information purposes, describes the behaviors of various Object methods. > > It's a shame this isn't the home for identityHashCode, but oh well. The "no members" policy is a safe baseline, but I suppose we could entertain relaxing it. Adding a method to IdentityObject is about as risky as adding a method to Object?possible, but touches (almost) every class in existence, so proceed with caution. What I had in mind was re-specifying things like Object.equals here. In a sense, it's safer than an entirely new name, but without having worked through the details, I worry about subtle changes to JVM behavior when these methods are present in the class file. From daniel.smith at oracle.com Wed Sep 9 02:08:54 2020 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 8 Sep 2020 20:08:54 -0600 Subject: EG meeting, 2020-09-09 Message-ID: <2AB14FE5-4D7E-4A48-9EAF-637FDDA001BA@oracle.com> The next EG Zoom meeting is Wednesday, 4pm UTC (12pm EDT, 9am PDT). There may not be much to talk about, and if so we can wrap up quickly. A couple of follow-ups from last week: - "IdentityObject & abstract superclasses": I put together a concrete summary of what to do with IdentityObject in the language/JVM/APIs - "Re-interpreting 'new Object()'": I wrote up concrete details on how we'd like to support results from 'new Object()' that implement IdentityObject From daniel.smith at oracle.com Wed Sep 9 17:15:38 2020 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 9 Sep 2020 11:15:38 -0600 Subject: EG meeting, 2020-09-09 In-Reply-To: <2AB14FE5-4D7E-4A48-9EAF-637FDDA001BA@oracle.com> References: <2AB14FE5-4D7E-4A48-9EAF-637FDDA001BA@oracle.com> Message-ID: <4E6C8DDE-8AFF-49B9-9A6E-EB5BD450BF31@oracle.com> Summarizing: > On Sep 8, 2020, at 8:08 PM, Dan Smith wrote: > > - "IdentityObject & abstract superclasses": I put together a concrete summary of what to do with IdentityObject in the language/JVM/APIs Dan H. is concerned that any special treatment for IdentityObject will be more trouble than its worth. This implies: - IdentityObject shouldn't be hidden by any reflection methods - Tools that inject methods into IdentityObject will be able to resolve/invoke those methods I agree that we're probably being premature in guarding against potential disruption, and for preview #1 it could make sense to just treat IdentityObject as a "real" interface and see if that causes any serious problems. (We know some tests will need to be changed, but that's probably not enough to justify permanent special treatment of the interface.) > - "Re-interpreting 'new Object()'": I wrote up concrete details on how we'd like to support results from 'new Object()' that implement IdentityObject Remi points out that the System class (or, say, Objects) is a place we could put a factory method if we want one but don't want to risk adding it to Object. I raised the possibility that we *could* use an implementation-specific class available only through a factory, rather than a public, standard class, as long as the JVMS treatment of 'new java/lang/Object' is sufficiently vague. Not clear this is useful, though. The behavior of invokespecial allows SimpleIdentityObjects to be constructed without running their methods. But JVMTI allows code to be injected into SimpleIdentityObject. Dan H. wondered how we should handle this anomaly. Possibilities: - Spec states that's just how SimpleIdentityObject works - JVMTI prevents any modifications to SimpleIdentityObject - Class loading rejects SimpleIdentityObject if it has a nonempty --- Remi raised another topic: lambda/method ref implementation classes are like value-based classes in that clients shouldn't make assumptions about identity. So they may be relevant to the @ValueBased warnings JEP. Specifically: - JVM synchronization checks could be applied to these classes?probably by having LambdaMetafactory apply the @ValueBased annotation to the class - javac could introduce some warnings. This *could* involve paying attention to @FunctionalInterface in addition to @ValueBased, although @FunctionalInterface makes weaker assumptions about its implementations (certainly reasonable for an identity class to implement Predicate). So it's a question of whether @FunctionalInterface is a strong enough signal that clients shouldn't be doing synchronization. We could do some experiments to see what we find in real code. From brian.goetz at oracle.com Wed Sep 9 18:15:50 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 9 Sep 2020 14:15:50 -0400 Subject: EG meeting, 2020-09-09 In-Reply-To: <4E6C8DDE-8AFF-49B9-9A6E-EB5BD450BF31@oracle.com> References: <2AB14FE5-4D7E-4A48-9EAF-637FDDA001BA@oracle.com> <4E6C8DDE-8AFF-49B9-9A6E-EB5BD450BF31@oracle.com> Message-ID: > Remi points out that the System class (or, say, Objects) is a place we could put a factory method if we want one but don't want to risk adding it to Object. Looking at it from the other direction, I am not sure having a nominal SimpleIdentityObject class adds much value.? You can of course write a do-nothing identity class yourself: ??? class WednesdayIdentityClass extends Object { } Will anyone want to extend SIO?? There's no point, since any concrete class that extends Object already becomes an IdentityObject, so they'll just extend Object. Will anyone want to use it as a parameter type / type bound?? I doubt it; they'll use IdentityObject. Will anyone want to use it as a return type?? I don't see much point, because there's nothing a SIO can do that Object can't.? The only reason we're exposing it is as a replacement for `new Object()`, which we've deemed to be an idiom only for getting a unique identity.? If we did nothing, people could replace: ??? Object lock = new Object(); with ??? Object lock = new Object() { }; (and someone would brand it the "identity brace trick".)? But that's a little too obscure, so recommending ??? Object lock = Objects.newIdentity(); says exactly what you mean.? The precise typestate of the result is an implementation detail; the key is that a new identity is dispensed. > Remi raised another topic: lambda/method ref implementation classes are like value-based classes in that clients shouldn't make assumptions about identity. So they may be relevant to the @ValueBased warnings JEP. Yes, please.? Despite our best efforts in Lambda, we're already seeing whining about "But I depended on the identity of a lambda." From daniel.smith at oracle.com Wed Sep 9 20:04:10 2020 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 9 Sep 2020 14:04:10 -0600 Subject: EG meeting, 2020-09-09 In-Reply-To: References: <2AB14FE5-4D7E-4A48-9EAF-637FDDA001BA@oracle.com> <4E6C8DDE-8AFF-49B9-9A6E-EB5BD450BF31@oracle.com> Message-ID: > On Sep 9, 2020, at 12:15 PM, Brian Goetz wrote: > >> Remi points out that the System class (or, say, Objects) is a place we could put a factory method if we want one but don't want to risk adding it to Object. > > Looking at it from the other direction, I am not sure having a nominal SimpleIdentityObject class adds much value. You can of course write a do-nothing identity class yourself: > > class WednesdayIdentityClass extends Object { } > > Will anyone want to extend SIO? There's no point, since any concrete class that extends Object already becomes an IdentityObject, so they'll just extend Object. > > Will anyone want to use it as a parameter type / type bound? I doubt it; they'll use IdentityObject. > > Will anyone want to use it as a return type? I don't see much point, because there's nothing a SIO can do that Object can't. The only reason we're exposing it is as a replacement for `new Object()`, which we've deemed to be an idiom only for getting a unique identity. If we did nothing, people could replace: > > Object lock = new Object(); > > with > > Object lock = new Object() { }; > > (and someone would brand it the "identity brace trick".) But that's a little too obscure, so recommending > > Object lock = Objects.newIdentity(); > > says exactly what you mean. The precise typestate of the result is an implementation detail; the key is that a new identity is dispensed. Yes, this is all good from the language perspective. The outstanding bit is "what does the instruction 'new java/lang/Object' do?" The simple thing is for JVMS to say "an instance of java/lang/SimpleIdentityObject is created on the heap". If the class is private, the JVM implementation still knows what it is, so that's probably okay, but what does JVMS say? I don't want to phrase it in a way that, say, lets a JVM implementation interpret 'new java/lang/Object' as 'new java/lang/String' or something stupid like that. From brian.goetz at oracle.com Wed Sep 9 20:44:09 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 9 Sep 2020 16:44:09 -0400 Subject: EG meeting, 2020-09-09 In-Reply-To: References: <2AB14FE5-4D7E-4A48-9EAF-637FDDA001BA@oracle.com> <4E6C8DDE-8AFF-49B9-9A6E-EB5BD450BF31@oracle.com> Message-ID: <04465993-aa84-d0df-59a7-0c76228a0f0f@oracle.com> Sure, and what I want to avoid is having a requirement of the JVMS (not even the JVM!) turn into a user-visible artifact.? Having a public class whose spec says "I exist entirely for the implementation of X" seems likely to be distracting. Does it have to be nominal?? Can we say "`new j/l/Object` puts a reference to a new instance of a direct identity subclass of Object with no methods or fields on the top of the stack"? > Yes, this is all good from the language perspective. The outstanding bit is "what does the instruction 'new java/lang/Object' do?" The simple thing is for JVMS to say "an instance of java/lang/SimpleIdentityObject is created on the heap". > > If the class is private, the JVM implementation still knows what it is, so that's probably okay, but what does JVMS say? I don't want to phrase it in a way that, say, lets a JVM implementation interpret 'new java/lang/Object' as 'new java/lang/String' or something stupid like that. From mcnepp02 at googlemail.com Thu Sep 10 09:01:11 2020 From: mcnepp02 at googlemail.com (Gernot Neppert) Date: Thu, 10 Sep 2020 11:01:11 +0200 Subject: EG meeting, 2020-09-09 In-Reply-To: References: <2AB14FE5-4D7E-4A48-9EAF-637FDDA001BA@oracle.com> <4E6C8DDE-8AFF-49B9-9A6E-EB5BD450BF31@oracle.com> Message-ID: > But that's a little too obscure, so recommending > > Object lock = Objects.newIdentity(); > > says exactly what you mean. The precise typestate of the result is an > implementation detail; the key is that a new identity is dispensed. Shouldn't that rather be: IdentityObject lock = Objects.newIdentity(); Otherwise you would still get lots of warnings when trying to use the lock for synchronization. BTW, I'm still campaigning for java.lang.IdentityAware as the name for the new interface :) Am Mi., 9. Sept. 2020 um 20:18 Uhr schrieb Brian Goetz < brian.goetz at oracle.com>: > > Remi points out that the System class (or, say, Objects) is a place we > could put a factory method if we want one but don't want to risk adding it > to Object. > > Looking at it from the other direction, I am not sure having a nominal > SimpleIdentityObject class adds much value. You can of course write a > do-nothing identity class yourself: > > class WednesdayIdentityClass extends Object { } > > Will anyone want to extend SIO? There's no point, since any concrete > class that extends Object already becomes an IdentityObject, so they'll > just extend Object. > > Will anyone want to use it as a parameter type / type bound? I doubt > it; they'll use IdentityObject. > > Will anyone want to use it as a return type? I don't see much point, > because there's nothing a SIO can do that Object can't. The only reason > we're exposing it is as a replacement for `new Object()`, which we've > deemed to be an idiom only for getting a unique identity. If we did > nothing, people could replace: > > Object lock = new Object(); > > with > > Object lock = new Object() { }; > > (and someone would brand it the "identity brace trick".) But that's a > little too obscure, so recommending > > Object lock = Objects.newIdentity(); > > says exactly what you mean. The precise typestate of the result is an > implementation detail; the key is that a new identity is dispensed. > > > Remi raised another topic: lambda/method ref implementation classes are > like value-based classes in that clients shouldn't make assumptions about > identity. So they may be relevant to the @ValueBased warnings JEP. > > Yes, please. Despite our best efforts in Lambda, we're already seeing > whining about "But I depended on the identity of a lambda." > > > From daniel.smith at oracle.com Wed Sep 23 14:39:13 2020 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 23 Sep 2020 08:39:13 -0600 Subject: EG meeting *canceled*, 2020-09-23 Message-ID: Sorry for late notice, but it doesn't look like we've got anything new for today's meeting, so let's cancel. Next meeting October 7.