From noel at peralex.com Wed Aug 5 05:28:21 2009 From: noel at peralex.com (Noel Grandin) Date: Wed, 05 Aug 2009 14:28:21 +0200 Subject: General community and Process Questions (blog comment followups) In-Reply-To: <4A6F1EA5.1000709@sun.com> References: <6013007.1248727620865.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> <6713E780-FBF4-45F2-8CAD-96A223EB8BFD@zwitserloot.com> <4A6EE265.3090106@peralex.com> <15e8b9d20907280735l6567b8c7y4f9e8e513848f1c9@mail.gmail.com> <4A6F1EA5.1000709@sun.com> Message-ID: <4A797AE5.8030304@peralex.com> If someone sets up a wiki and gives me edit rights, I'll trawl the mailing list records and create some entries. If nothing else, it should help to jump-start the discussions for Coin2. (I was surprised to see that the openjdk website does not have a wiki - I thought that came for free with java.net hosting?) -- Noel Joseph D. Darcy wrote: > Neal Gafter wrote: >> Noel- >> >> This is a great idea; it would certainly help casual observers to >> follow the >> status of the proposals and discussion. That would also be useful as a >> starting point for any future Coin-like project. >> >> I volunteer to provide web hosting and software support if you'll >> agree to >> set up and maintain the Wiki based on the existing discussion record. >> Please let me know. >> > > I can set up a wiki under http://wikis.sun.com, as done for the Da > Vinci Machine Project (the JSR 292 RI). However, I will not actively > maintain a wiki so someone else would have to volunteer to do this > work. Additionally, one purpose of my Coin blog posts is to provide a > lower volume way to track what is going on; posts under > http://blogs.sun.com/main/tags/projectcoin provide news of major > developments and links to the latest versions of proposals, etc. > > -Joe Disclaimer: http://www.peralex.com/disclaimer.html From Joe.Darcy at Sun.COM Wed Aug 5 11:23:20 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 05 Aug 2009 11:23:20 -0700 Subject: General community and Process Questions (blog comment followups) In-Reply-To: <4A797AE5.8030304@peralex.com> References: <6013007.1248727620865.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> <6713E780-FBF4-45F2-8CAD-96A223EB8BFD@zwitserloot.com> <4A6EE265.3090106@peralex.com> <15e8b9d20907280735l6567b8c7y4f9e8e513848f1c9@mail.gmail.com> <4A6F1EA5.1000709@sun.com> <4A797AE5.8030304@peralex.com> Message-ID: <4A79CE18.5000705@sun.com> I'll look into creating a wiki for Project Coin under http://wikis.sun.com. Regards, -Joe Noel Grandin wrote: > If someone sets up a wiki and gives me edit rights, I'll trawl the > mailing list records and create some entries. > > If nothing else, it should help to jump-start the discussions for Coin2. > > (I was surprised to see that the openjdk website does not have a wiki - > I thought that came for free with java.net hosting?) > > -- Noel > > Joseph D. Darcy wrote: > >> Neal Gafter wrote: >> >>> Noel- >>> >>> This is a great idea; it would certainly help casual observers to >>> follow the >>> status of the proposals and discussion. That would also be useful as a >>> starting point for any future Coin-like project. >>> >>> I volunteer to provide web hosting and software support if you'll >>> agree to >>> set up and maintain the Wiki based on the existing discussion record. >>> Please let me know. >>> >>> >> I can set up a wiki under http://wikis.sun.com, as done for the Da >> Vinci Machine Project (the JSR 292 RI). However, I will not actively >> maintain a wiki so someone else would have to volunteer to do this >> work. Additionally, one purpose of my Coin blog posts is to provide a >> lower volume way to track what is going on; posts under >> http://blogs.sun.com/main/tags/projectcoin provide news of major >> developments and links to the latest versions of proposals, etc. >> >> -Joe >> > > > Disclaimer: http://www.peralex.com/disclaimer.html > > > From gzoller at hotmail.com Sun Aug 9 09:24:04 2009 From: gzoller at hotmail.com (Greg Zoller) Date: Sun, 9 Aug 2009 12:24:04 -0400 Subject: A Late Entry Message-ID: Members of coin-dev... I'm writing to submit a late proposal for the Java language, if not for initial Java 7 release (probably too late) but perhaps for a later release. Below is the proposal form. Plain text editor formatting is pretty inconsistent, so apologies if it looks poorly formatted when you see it. Project Coin Late Submission: Hiding Accessors at Compile Time AUTHOR: Greg Zoller gzoller(atsign)hotmail.com OVERVIEW: Feature Summary: De-clutter classes littered with accessors by having the compiler auto-generate trivial accessors for data members denoted with a @property annotation. Major Advantage: Would eliminate lots (and lots) of messy get/set code without losing the benefits of having an accessor for the times you really need them. The proposed approach should not break any existing code not written to take advantage of the new capability. Major Benefit: Less cluttered code! Removes (or more specifically hides behind the compiler) the clumsy construct of accessors without losing the purpose and benfits of their existence. In other words, I want property accessor capability--I just don't want to see them! Major Disadvantage: None that come to mind--I'm sure someone will contribute a disadvantage. Alternatives: Leave things the way they are. EXAMPLES: /* Today */ public class Foo { private String name; // no accessors for name private int age; private double balance; private String comment; public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } public double getBalance() { return this.balance; } public void setComment(String comment) { this.comment = comment; } } /* Proposed */ public class Foo { private String name; // no accessors generated @property private int age; // both get/set generated @property(GET) private double balance; // getter generated, no setter @property(SET) private String comment; // setter generated, no getter } // Code would use these properties via their generated // accessors as they do now: foo.setAge(foo.getAge() + 10); // EVEN BETTER... the compiler can try to resolve data member // access according to a scope/visibility hierarchy: // public member, protected member, private member, // inserted getter/setter call // If this can be done in the compiler then old code can still // call the accessors like always while new code could simply // have: foo.age += 10; System.out.println("Age: "+foo.age); // This looks as clean as direct data member access but age // remains private with all the benefits of having accessor // protection. In the example above assuming no public, // protected, or private visibility for age exists the compiler // will insert a call to foo.getAge() for the programmer if age // is a @property field (otherwise its a compile error). // NOTE: The compiler won't auto-generate a getter or setter if // one already has been specified by the programmer, allowing // full control like we have now: public class Foo { @property private int age; // only a trivial getter generated--setter exists public void setAge(int age) { msg.notify("Someone's tampering with age!"); this.age = age; } } // The compiler would exercise precedence logic in deciding // whether to insert a call to the accessors or not package A; public class Foo { @property private int age; // only setter generated--getter exists public int getAge() { System.out.println("Getter called!"); return this.age; } public void something() { int anotherAge = this.age; // private visibility is valid--no compiler-inserted // call to this.getAge() here int oneMoreAge = this.getAge(); // explicit call to getter ok--just like today } } package B; public class Bar { public void blah(Foo foo) { System.out.println(foo.age); // Compiler can't resolve public, protected, or // private visibility to foo.age so a call to the // generated foo.getAge() accessor is inserted } } DETAILS Specification: Add the FIELD-targeted @property annotation to the language. Without parameters this will cause the generation of both a getter and setter unless one is already given by the programmer. Optional parameters GET or SET (@property(GET) or @property(SET)) would only attempt to generate the getter or setter respectively. I don't think Java grammar would be affected (?). Compilation: Out of my depth here. The auto-generation feature *should* be very straightforward as I would hope all the needed info to create the getters/setters is available at compile-time. I'm less clear on whether the compiler would be able to do the auto-resolution so you could just use foo.age and wouldn't be forced to call foo.getAge()/foo.setAge(), but I'm hopeful this is also possible, as it would be a great feature. This logic would have to support a hierarchy of resolution so that if 'age' was a public data member then public access would take precedence over trying to call the accessor method. Likewise protected and private access would take precedence over the getter if normal visibility rules allowed this mode of access. Testing: Hmm... Library Support: Shouldn't require any library support Reflective APIs: Existing APIs should be fine. The generated getters/setters would be reflectively accessible since once they are generated by the compiler they are no different than if the programmer had written them. Other Changes: None come to mine. Migration: No conversion necessary. Normal getter/setter code in common use today would still work and could live seamlessly in parallel with code using the new features. COMPATIBILITY: Breaking Changes: No code should break due to the changes proposed Existing Programs: Existing code should live seamlessly in parallel to these changes. If the compiler access precidence feature is implemented then newly written code can take advantage of this ability when calling existing unmodified code. For example: // Existing code public class Foo { private int age; public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } } // New code foo.age = 10; // compiler would first see if a public/protected/private // visible age data member existed, and since there is none // a call to getAge() would be inserted during compile time // thus using the new feature to seamlessly interact with // legacy code without altering semantics REFERENCES: N/A _________________________________________________________________ Get free photo software from Windows Live http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL:en-US:SI_PH_software:082009 From neal at gafter.com Sun Aug 9 11:22:29 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 9 Aug 2009 11:22:29 -0700 Subject: A Late Entry In-Reply-To: References: Message-ID: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> Annotations are not an appropriate "back door" for adding syntax to the Java programming language. I suggest you instead consider context-sensitive keywords. On Sun, Aug 9, 2009 at 9:24 AM, Greg Zoller wrote: > > Members of coin-dev... I'm writing to submit a late proposal for the Java > language, if not for initial Java 7 release (probably too late) but perhaps > for a later release. Below is the proposal form. Plain text editor > formatting is pretty inconsistent, so apologies if it looks poorly formatted > when you see it. > > > Project Coin > > Late Submission: Hiding Accessors at Compile Time > > AUTHOR: Greg Zoller > gzoller(atsign)hotmail.com > > OVERVIEW: > > Feature Summary: > De-clutter classes littered with accessors by having the > compiler auto-generate trivial accessors for data members > denoted with a @property annotation. > > Major Advantage: > Would eliminate lots (and lots) of messy get/set code > without losing the benefits of having an accessor for the > times you really need them. The proposed approach should > not break any existing code not written to take advantage > of the new capability. > > Major Benefit: > Less cluttered code! Removes (or more specifically hides > behind the compiler) the clumsy construct of accessors > without losing the purpose and benfits of their existence. > In other words, I want property accessor capability--I > just don't want to see them! > > Major Disadvantage: > None that come to mind--I'm sure someone will contribute a > disadvantage. > > Alternatives: > Leave things the way they are. > > EXAMPLES: > > /* Today */ > public class Foo { > private String name; // no accessors for name > private int age; > private double balance; > private String comment; > > public int getAge() { return this.age; } > public void setAge(int age) { this.age = age; } > public double getBalance() { return this.balance; } > public void setComment(String comment) { > this.comment = comment; } > } > > /* Proposed */ > public class Foo { > private String name; // no accessors generated > @property private int age; // both get/set generated > @property(GET) private double balance; // getter generated, no > setter > @property(SET) private String comment; // setter generated, no > getter > } > > // Code would use these properties via their generated > // accessors as they do now: > foo.setAge(foo.getAge() + 10); > > // EVEN BETTER... the compiler can try to resolve data member > // access according to a scope/visibility hierarchy: > // public member, protected member, private member, > // inserted getter/setter call > > // If this can be done in the compiler then old code can still > // call the accessors like always while new code could simply > // have: > > foo.age += 10; > System.out.println("Age: "+foo.age); > > // This looks as clean as direct data member access but age > // remains private with all the benefits of having accessor > // protection. In the example above assuming no public, > // protected, or private visibility for age exists the compiler > // will insert a call to foo.getAge() for the programmer if age > // is a @property field (otherwise its a compile error). > > // NOTE: The compiler won't auto-generate a getter or setter if > // one already has been specified by the programmer, allowing > // full control like we have now: > > public class Foo { > @property private int age; // only a trivial getter > generated--setter exists > public void setAge(int age) { > msg.notify("Someone's tampering with age!"); > this.age = age; > } > } > > // The compiler would exercise precedence logic in deciding > // whether to insert a call to the accessors or not > > package A; > public class Foo { > @property private int age; // only setter generated--getter exists > public int getAge() { > System.out.println("Getter called!"); > return this.age; > } > public void something() { > int anotherAge = this.age; > // private visibility is valid--no compiler-inserted > // call to this.getAge() here > > int oneMoreAge = this.getAge(); > // explicit call to getter ok--just like today > } > } > > package B; > public class Bar { > public void blah(Foo foo) { > System.out.println(foo.age); > // Compiler can't resolve public, protected, or > // private visibility to foo.age so a call to the > // generated foo.getAge() accessor is inserted > } > } > > DETAILS > > Specification: > Add the FIELD-targeted @property annotation to the > language. Without parameters this will cause the > generation of both a getter and setter unless one is > already given by the programmer. > > Optional parameters GET or SET (@property(GET) or > @property(SET)) would only attempt to generate the getter > or setter respectively. I don't think Java grammar would > be affected (?). > > Compilation: > Out of my depth here. The auto-generation feature *should* > be very straightforward as I would hope all the needed info > to create the getters/setters is available at compile-time. > I'm less clear on whether the compiler would be able to do > the auto-resolution so you could just use foo.age and > wouldn't be forced to call foo.getAge()/foo.setAge(), but > I'm hopeful this is also possible, as it would be a great > feature. > > This logic would have to support a hierarchy of resolution > so that if 'age' was a public data member then public > access would take precedence over trying to call the > accessor method. Likewise protected and private access > would take precedence over the getter if normal > visibility rules allowed this mode of access. > > Testing: > Hmm... > > Library Support: > Shouldn't require any library support > > Reflective APIs: > Existing APIs should be fine. The generated > getters/setters would be reflectively accessible since once > they are generated by the compiler they are no different > than if the programmer had written them. > > Other Changes: > None come to mine. > > Migration: > No conversion necessary. Normal getter/setter code in > common use today would still work and could live seamlessly > in parallel with code using the new features. > > COMPATIBILITY: > > Breaking Changes: > No code should break due to the changes proposed > > Existing Programs: > Existing code should live seamlessly in parallel to these > changes. If the compiler access precidence feature is > implemented then newly written code can take advantage of > this ability when calling existing unmodified code. For > example: > > // Existing code > public class Foo { > private int age; > public int getAge() { return this.age; } > public void setAge(int age) { this.age = age; } > } > > // New code > foo.age = 10; > > // compiler would first see if a public/protected/private > // visible age data member existed, and since there is none > // a call to getAge() would be inserted during compile time > // thus using the new feature to seamlessly interact with > // legacy code without altering semantics > > REFERENCES: > N/A > > > _________________________________________________________________ > Get free photo software from Windows Live > > http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL:en-US:SI_PH_software:082009 > > From Joe.Darcy at Sun.COM Sun Aug 9 12:38:41 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 09 Aug 2009 12:38:41 -0700 Subject: A Late Entry In-Reply-To: References: Message-ID: <4A7F25C1.4000207@sun.com> Hello. As you allude to, the Project Coin call for proposals phase closed many months ago. Coin received several proposal in the vein of adding properties support. Those proposals were not selected for JDK 7 and the procedures for future major JDK releases have not yet been established. -Joe Greg Zoller wrote: > Members of coin-dev... I'm writing to submit a late proposal for the Java language, if not for initial Java 7 release (probably too late) but perhaps for a later release. Below is the proposal form. Plain text editor formatting is pretty inconsistent, so apologies if it looks poorly formatted when you see it. > > > Project Coin > > Late Submission: Hiding Accessors at Compile Time > > AUTHOR: Greg Zoller > gzoller(atsign)hotmail.com > > OVERVIEW: > > Feature Summary: > De-clutter classes littered with accessors by having the > compiler auto-generate trivial accessors for data members > denoted with a @property annotation. > > Major Advantage: > Would eliminate lots (and lots) of messy get/set code > without losing the benefits of having an accessor for the > times you really need them. The proposed approach should > not break any existing code not written to take advantage > of the new capability. > > Major Benefit: > Less cluttered code! Removes (or more specifically hides > behind the compiler) the clumsy construct of accessors > without losing the purpose and benfits of their existence. > In other words, I want property accessor capability--I > just don't want to see them! > > Major Disadvantage: > None that come to mind--I'm sure someone will contribute a > disadvantage. > > Alternatives: > Leave things the way they are. > > EXAMPLES: > > /* Today */ > public class Foo { > private String name; // no accessors for name > private int age; > private double balance; > private String comment; > > public int getAge() { return this.age; } > public void setAge(int age) { this.age = age; } > public double getBalance() { return this.balance; } > public void setComment(String comment) { > this.comment = comment; } > } > > /* Proposed */ > public class Foo { > private String name; // no accessors generated > @property private int age; // both get/set generated > @property(GET) private double balance; // getter generated, no setter > @property(SET) private String comment; // setter generated, no getter > } > > // Code would use these properties via their generated > // accessors as they do now: > foo.setAge(foo.getAge() + 10); > > // EVEN BETTER... the compiler can try to resolve data member > // access according to a scope/visibility hierarchy: > // public member, protected member, private member, > // inserted getter/setter call > > // If this can be done in the compiler then old code can still > // call the accessors like always while new code could simply > // have: > > foo.age += 10; > System.out.println("Age: "+foo.age); > > // This looks as clean as direct data member access but age > // remains private with all the benefits of having accessor > // protection. In the example above assuming no public, > // protected, or private visibility for age exists the compiler > // will insert a call to foo.getAge() for the programmer if age > // is a @property field (otherwise its a compile error). > > // NOTE: The compiler won't auto-generate a getter or setter if > // one already has been specified by the programmer, allowing > // full control like we have now: > > public class Foo { > @property private int age; // only a trivial getter generated--setter exists > public void setAge(int age) { > msg.notify("Someone's tampering with age!"); > this.age = age; > } > } > > // The compiler would exercise precedence logic in deciding > // whether to insert a call to the accessors or not > > package A; > public class Foo { > @property private int age; // only setter generated--getter exists > public int getAge() { > System.out.println("Getter called!"); > return this.age; > } > public void something() { > int anotherAge = this.age; > // private visibility is valid--no compiler-inserted > // call to this.getAge() here > > int oneMoreAge = this.getAge(); > // explicit call to getter ok--just like today > } > } > > package B; > public class Bar { > public void blah(Foo foo) { > System.out.println(foo.age); > // Compiler can't resolve public, protected, or > // private visibility to foo.age so a call to the > // generated foo.getAge() accessor is inserted > } > } > > DETAILS > > Specification: > Add the FIELD-targeted @property annotation to the > language. Without parameters this will cause the > generation of both a getter and setter unless one is > already given by the programmer. > > Optional parameters GET or SET (@property(GET) or > @property(SET)) would only attempt to generate the getter > or setter respectively. I don't think Java grammar would > be affected (?). > > Compilation: > Out of my depth here. The auto-generation feature *should* > be very straightforward as I would hope all the needed info > to create the getters/setters is available at compile-time. > I'm less clear on whether the compiler would be able to do > the auto-resolution so you could just use foo.age and > wouldn't be forced to call foo.getAge()/foo.setAge(), but > I'm hopeful this is also possible, as it would be a great > feature. > > This logic would have to support a hierarchy of resolution > so that if 'age' was a public data member then public > access would take precedence over trying to call the > accessor method. Likewise protected and private access > would take precedence over the getter if normal > visibility rules allowed this mode of access. > > Testing: > Hmm... > > Library Support: > Shouldn't require any library support > > Reflective APIs: > Existing APIs should be fine. The generated > getters/setters would be reflectively accessible since once > they are generated by the compiler they are no different > than if the programmer had written them. > > Other Changes: > None come to mine. > > Migration: > No conversion necessary. Normal getter/setter code in > common use today would still work and could live seamlessly > in parallel with code using the new features. > > COMPATIBILITY: > > Breaking Changes: > No code should break due to the changes proposed > > Existing Programs: > Existing code should live seamlessly in parallel to these > changes. If the compiler access precidence feature is > implemented then newly written code can take advantage of > this ability when calling existing unmodified code. For > example: > > // Existing code > public class Foo { > private int age; > public int getAge() { return this.age; } > public void setAge(int age) { this.age = age; } > } > > // New code > foo.age = 10; > > // compiler would first see if a public/protected/private > // visible age data member existed, and since there is none > // a call to getAge() would be inserted during compile time > // thus using the new feature to seamlessly interact with > // legacy code without altering semantics > > REFERENCES: > N/A > > > _________________________________________________________________ > Get free photo software from Windows Live > http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL:en-US:SI_PH_software:082009 > > From Joe.Darcy at Sun.COM Tue Aug 11 18:43:46 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 11 Aug 2009 18:43:46 -0700 Subject: General community and Process Questions (blog comment followups) In-Reply-To: <4A79CE18.5000705@sun.com> References: <6013007.1248727620865.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> <6713E780-FBF4-45F2-8CAD-96A223EB8BFD@zwitserloot.com> <4A6EE265.3090106@peralex.com> <15e8b9d20907280735l6567b8c7y4f9e8e513848f1c9@mail.gmail.com> <4A6F1EA5.1000709@sun.com> <4A797AE5.8030304@peralex.com> <4A79CE18.5000705@sun.com> Message-ID: <4A821E52.5090008@sun.com> Joseph D. Darcy wrote: > I'll look into creating a wiki for Project Coin under http://wikis.sun.com. Created: http://wikis.sun.com/display/ProjectCoin/Home -Joe > > Regards, > > -Joe > > > Noel Grandin wrote: >> If someone sets up a wiki and gives me edit rights, I'll trawl the >> mailing list records and create some entries. >> >> If nothing else, it should help to jump-start the discussions for Coin2. >> >> (I was surprised to see that the openjdk website does not have a wiki - >> I thought that came for free with java.net hosting?) >> >> -- Noel >> >> Joseph D. Darcy wrote: >> >>> Neal Gafter wrote: >>> >>>> Noel- >>>> >>>> This is a great idea; it would certainly help casual observers to >>>> follow the >>>> status of the proposals and discussion. That would also be useful as a >>>> starting point for any future Coin-like project. >>>> >>>> I volunteer to provide web hosting and software support if you'll >>>> agree to >>>> set up and maintain the Wiki based on the existing discussion record. >>>> Please let me know. >>>> >>> I can set up a wiki under http://wikis.sun.com, as done for the Da >>> Vinci Machine Project (the JSR 292 RI). However, I will not actively >>> maintain a wiki so someone else would have to volunteer to do this >>> work. Additionally, one purpose of my Coin blog posts is to provide a >>> lower volume way to track what is going on; posts under >>> http://blogs.sun.com/main/tags/projectcoin provide news of major >>> developments and links to the latest versions of proposals, etc. >>> >>> -Joe >>> >> >> >> Disclaimer: http://www.peralex.com/disclaimer.html >> >> >> > From ted at tedneward.com Sat Aug 15 12:01:16 2009 From: ted at tedneward.com (Ted Neward) Date: Sat, 15 Aug 2009 12:01:16 -0700 Subject: A Late Entry In-Reply-To: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> Message-ID: <03d301ca1dda$c55ccdb0$50166910$@com> Oh, but come on, Neal, everybody's doing it.... *cough* JSR 308 *cough* I'll be 100% honest: I'm really worried that 308 is going to open up a whole can of worms and people are going to do exactly that: create their own customized flavors of Java by using annotations to replace keywords. But that's for a different mailing list, I suppose. Ted Neward Java, .NET, XML Services Consulting, Teaching, Speaking, Writing http://www.tedneward.com > -----Original Message----- > From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- > bounces at openjdk.java.net] On Behalf Of Neal Gafter > Sent: Sunday, August 09, 2009 11:22 AM > To: Greg Zoller > Cc: coin-dev at openjdk.java.net > Subject: Re: A Late Entry > > Annotations are not an appropriate "back door" for adding syntax to the > Java > programming language. I suggest you instead consider context-sensitive > keywords. > > On Sun, Aug 9, 2009 at 9:24 AM, Greg Zoller > wrote: > > > > > Members of coin-dev... I'm writing to submit a late proposal for the > Java > > language, if not for initial Java 7 release (probably too late) but > perhaps > > for a later release. Below is the proposal form. Plain text editor > > formatting is pretty inconsistent, so apologies if it looks poorly > formatted > > when you see it. > > > > > > Project Coin > > > > Late Submission: Hiding Accessors at Compile Time > > > > AUTHOR: Greg Zoller > > gzoller(atsign)hotmail.com > > > > OVERVIEW: > > > > Feature Summary: > > De-clutter classes littered with accessors by having the > > compiler auto-generate trivial accessors for data members > > denoted with a @property annotation. > > > > Major Advantage: > > Would eliminate lots (and lots) of messy get/set code > > without losing the benefits of having an accessor for the > > times you really need them. The proposed approach should > > not break any existing code not written to take advantage > > of the new capability. > > > > Major Benefit: > > Less cluttered code! Removes (or more specifically hides > > behind the compiler) the clumsy construct of accessors > > without losing the purpose and benfits of their existence. > > In other words, I want property accessor capability--I > > just don't want to see them! > > > > Major Disadvantage: > > None that come to mind--I'm sure someone will contribute a > > disadvantage. > > > > Alternatives: > > Leave things the way they are. > > > > EXAMPLES: > > > > /* Today */ > > public class Foo { > > private String name; // no accessors for name > > private int age; > > private double balance; > > private String comment; > > > > public int getAge() { return this.age; } > > public void setAge(int age) { this.age = age; } > > public double getBalance() { return this.balance; } > > public void setComment(String comment) { > > this.comment = comment; } > > } > > > > /* Proposed */ > > public class Foo { > > private String name; // no accessors generated > > @property private int age; // both get/set generated > > @property(GET) private double balance; // getter generated, > no > > setter > > @property(SET) private String comment; // setter generated, > no > > getter > > } > > > > // Code would use these properties via their generated > > // accessors as they do now: > > foo.setAge(foo.getAge() + 10); > > > > // EVEN BETTER... the compiler can try to resolve data member > > // access according to a scope/visibility hierarchy: > > // public member, protected member, private member, > > // inserted getter/setter call > > > > // If this can be done in the compiler then old code can still > > // call the accessors like always while new code could simply > > // have: > > > > foo.age += 10; > > System.out.println("Age: "+foo.age); > > > > // This looks as clean as direct data member access but age > > // remains private with all the benefits of having accessor > > // protection. In the example above assuming no public, > > // protected, or private visibility for age exists the compiler > > // will insert a call to foo.getAge() for the programmer if age > > // is a @property field (otherwise its a compile error). > > > > // NOTE: The compiler won't auto-generate a getter or setter if > > // one already has been specified by the programmer, allowing > > // full control like we have now: > > > > public class Foo { > > @property private int age; // only a trivial getter > > generated--setter exists > > public void setAge(int age) { > > msg.notify("Someone's tampering with age!"); > > this.age = age; > > } > > } > > > > // The compiler would exercise precedence logic in deciding > > // whether to insert a call to the accessors or not > > > > package A; > > public class Foo { > > @property private int age; // only setter generated--getter > exists > > public int getAge() { > > System.out.println("Getter called!"); > > return this.age; > > } > > public void something() { > > int anotherAge = this.age; > > // private visibility is valid--no compiler-inserted > > // call to this.getAge() here > > > > int oneMoreAge = this.getAge(); > > // explicit call to getter ok--just like today > > } > > } > > > > package B; > > public class Bar { > > public void blah(Foo foo) { > > System.out.println(foo.age); > > // Compiler can't resolve public, protected, or > > // private visibility to foo.age so a call to the > > // generated foo.getAge() accessor is inserted > > } > > } > > > > DETAILS > > > > Specification: > > Add the FIELD-targeted @property annotation to the > > language. Without parameters this will cause the > > generation of both a getter and setter unless one is > > already given by the programmer. > > > > Optional parameters GET or SET (@property(GET) or > > @property(SET)) would only attempt to generate the getter > > or setter respectively. I don't think Java grammar would > > be affected (?). > > > > Compilation: > > Out of my depth here. The auto-generation feature *should* > > be very straightforward as I would hope all the needed info > > to create the getters/setters is available at compile-time. > > I'm less clear on whether the compiler would be able to do > > the auto-resolution so you could just use foo.age and > > wouldn't be forced to call foo.getAge()/foo.setAge(), but > > I'm hopeful this is also possible, as it would be a great > > feature. > > > > This logic would have to support a hierarchy of resolution > > so that if 'age' was a public data member then public > > access would take precedence over trying to call the > > accessor method. Likewise protected and private access > > would take precedence over the getter if normal > > visibility rules allowed this mode of access. > > > > Testing: > > Hmm... > > > > Library Support: > > Shouldn't require any library support > > > > Reflective APIs: > > Existing APIs should be fine. The generated > > getters/setters would be reflectively accessible since once > > they are generated by the compiler they are no different > > than if the programmer had written them. > > > > Other Changes: > > None come to mine. > > > > Migration: > > No conversion necessary. Normal getter/setter code in > > common use today would still work and could live seamlessly > > in parallel with code using the new features. > > > > COMPATIBILITY: > > > > Breaking Changes: > > No code should break due to the changes proposed > > > > Existing Programs: > > Existing code should live seamlessly in parallel to these > > changes. If the compiler access precidence feature is > > implemented then newly written code can take advantage of > > this ability when calling existing unmodified code. For > > example: > > > > // Existing code > > public class Foo { > > private int age; > > public int getAge() { return this.age; } > > public void setAge(int age) { this.age = age; } > > } > > > > // New code > > foo.age = 10; > > > > // compiler would first see if a public/protected/private > > // visible age data member existed, and since there is none > > // a call to getAge() would be inserted during compile time > > // thus using the new feature to seamlessly interact with > > // legacy code without altering semantics > > > > REFERENCES: > > N/A > > > > > > _________________________________________________________________ > > Get free photo software from Windows Live > > > > > http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL > :en-US:SI_PH_software:082009 > > > > From fyaoxy at gmail.com Sat Aug 15 17:38:01 2009 From: fyaoxy at gmail.com (=?UTF-8?B?5ZCR6ZuF?=) Date: Sun, 16 Aug 2009 08:38:01 +0800 Subject: A Late Entry In-Reply-To: <03d301ca1dda$c55ccdb0$50166910$@com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> Message-ID: <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> Hi, 2009/8/16 Ted Neward : > Oh, but come on, Neal, everybody's doing it.... *cough* JSR 308 *cough* > > I'll be 100% honest: I'm really worried that 308 is going to open up a whole > can of worms and people are going to do exactly that: create their own > customized flavors of Java by using annotations to replace keywords. But > that's for a different mailing list, I suppose. Agreed, but I not think it worth worried. Everyone have own flavors, IMO tools author should not force others flavor. Of cause the code with all flavors should work with each other, that just ok. back to the topic. 1,Property annotation maybe no the best alternative. I agreed with context-sensitive, through I'm fair even ten years after it still be a future. 2,The property proposal from based on field, I called it B(ottom)2T(op) style. I talk a T2B style with Adam: property can be focused on method and/or field, the field not must. some kind same as JavaBean properties. most important, which is interface style. > Ted Neward > Java, .NET, XML Services > Consulting, Teaching, Speaking, Writing > http://www.tedneward.com > >> -----Original Message----- >> From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- >> bounces at openjdk.java.net] On Behalf Of Neal Gafter >> Sent: Sunday, August 09, 2009 11:22 AM >> To: Greg Zoller >> Cc: coin-dev at openjdk.java.net >> Subject: Re: A Late Entry >> >> Annotations are not an appropriate "back door" for adding syntax to the >> Java >> programming language. ?I suggest you instead consider context-sensitive >> keywords. >> >> On Sun, Aug 9, 2009 at 9:24 AM, Greg Zoller >> wrote: >> >> > >> > Members of coin-dev... ?I'm writing to submit a late proposal for the >> Java >> > language, if not for initial Java 7 release (probably too late) but >> perhaps >> > for a later release. ?Below is the proposal form. ?Plain text editor >> > formatting is pretty inconsistent, so apologies if it looks poorly >> formatted >> > when you see it. >> > >> > >> > Project Coin >> > >> > Late Submission: Hiding Accessors at Compile Time >> > >> > AUTHOR: ?Greg Zoller >> > ? ? ? ? gzoller(atsign)hotmail.com >> > >> > OVERVIEW: >> > >> > ? ?Feature Summary: >> > ? ? ? ?De-clutter classes littered with accessors by having the >> > ? ? ? ?compiler auto-generate trivial accessors for data members >> > ? ? ? ?denoted with a @property annotation. >> > >> > ? ?Major Advantage: >> > ? ? ? ?Would eliminate lots (and lots) of messy get/set code >> > ? ? ? ?without losing the benefits of having an accessor for the >> > ? ? ? ?times you really need them. ?The proposed approach should >> > ? ? ? ?not break any existing code not written to take advantage >> > ? ? ? ?of the new capability. >> > >> > ? ?Major Benefit: >> > ? ? ? ?Less cluttered code! ?Removes (or more specifically hides >> > ? ? ? ?behind the compiler) the clumsy construct of accessors >> > ? ? ? ?without losing the purpose and benfits of their existence. >> > ? ? ? ?In other words, I want property accessor capability--I >> > ? ? ? ?just don't want to see them! >> > >> > ? ?Major Disadvantage: >> > ? ? ? ?None that come to mind--I'm sure someone will contribute a >> > ? ? ? ?disadvantage. >> > >> > ? ?Alternatives: >> > ? ? ? ?Leave things the way they are. >> > >> > EXAMPLES: >> > >> > ? ?/* Today */ >> > ? ?public class Foo { >> > ? ? ? ?private String name; ?// no accessors for name >> > ? ? ? ?private int age; >> > ? ? ? ?private double balance; >> > ? ? ? ?private String comment; >> > >> > ? ? ? ?public int getAge() { return this.age; } >> > ? ? ? ?public void setAge(int age) { this.age = age; } >> > ? ? ? ?public double getBalance() { return this.balance; } >> > ? ? ? ?public void setComment(String comment) { >> > ? ? ? ? ? ?this.comment = comment; } >> > ? ?} >> > >> > ? ?/* Proposed */ >> > ? ?public class Foo { >> > ? ? ? ?private String name; ?// no accessors generated >> > ? ? ? ?@property private int age; ?// both get/set generated >> > ? ? ? ?@property(GET) private double balance; ?// getter generated, >> no >> > setter >> > ? ? ? ?@property(SET) private String comment; ?// setter generated, >> no >> > getter >> > ? ?} >> > >> > ? ?// Code would use these properties via their generated >> > ? ?// accessors as they do now: >> > ? ?foo.setAge(foo.getAge() + 10); >> > >> > ? ?// EVEN BETTER... the compiler can try to resolve data member >> > ? ?// access according to a scope/visibility hierarchy: >> > ? ?// ? ? ? public member, protected member, private member, >> > ? ?// ? ? ? inserted getter/setter call >> > >> > ? ?// If this can be done in the compiler then old code can still >> > ? ?// call the accessors like always while new code could simply >> > ? ?// have: >> > >> > ? ?foo.age += 10; >> > ? ?System.out.println("Age: "+foo.age); >> > >> > ? ?// This looks as clean as direct data member access but age >> > ? ?// remains private with all the benefits of having accessor >> > ? ?// protection. ?In the example above assuming no public, >> > ? ?// protected, or private visibility for age exists the compiler >> > ? ?// will insert a call to foo.getAge() for the programmer if age >> > ? ?// is a @property field (otherwise its a compile error). >> > >> > ? ?// NOTE: ?The compiler won't auto-generate a getter or setter if >> > ? ?// one already has been specified by the programmer, allowing >> > ? ?// full control like we have now: >> > >> > ? ?public class Foo { >> > ? ? ? ?@property private int age; ?// only a trivial getter >> > generated--setter exists >> > ? ? ? ?public void setAge(int age) { >> > ? ? ? ? ? ?msg.notify("Someone's tampering with age!"); >> > ? ? ? ? ? ?this.age = age; >> > ? ? ? ?} >> > ? ?} >> > >> > ? ?// The compiler would exercise precedence logic in deciding >> > ? ?// whether to insert a call to the accessors or not >> > >> > ? ?package A; >> > ? ?public class Foo { >> > ? ? ? ?@property private int age; ?// only setter generated--getter >> exists >> > ? ? ? ?public int getAge() { >> > ? ? ? ? ? ?System.out.println("Getter called!"); >> > ? ? ? ? ? ?return this.age; >> > ? ? ? ?} >> > ? ? ? ?public void something() { >> > ? ? ? ? ? ?int anotherAge = this.age; >> > ? ? ? ? ? ?// private visibility is valid--no compiler-inserted >> > ? ? ? ? ? ?// call to this.getAge() here >> > >> > ? ? ? ? ? ?int oneMoreAge = this.getAge(); >> > ? ? ? ? ? ?// explicit call to getter ok--just like today >> > ? ? ? ?} >> > ? ?} >> > >> > ? ?package B; >> > ? ?public class Bar { >> > ? ? ? ?public void blah(Foo foo) { >> > ? ? ? ? ? ?System.out.println(foo.age); >> > ? ? ? ? ? ?// Compiler can't resolve public, protected, or >> > ? ? ? ? ? ?// private visibility to foo.age so a call to the >> > ? ? ? ? ? ?// generated foo.getAge() accessor is inserted >> > ? ? ? ?} >> > ? ?} >> > >> > DETAILS >> > >> > ? ?Specification: >> > ? ? ? ?Add the FIELD-targeted @property annotation to the >> > ? ? ? ?language. ?Without parameters this will cause the >> > ? ? ? ?generation of both a getter and setter unless one is >> > ? ? ? ?already given by the programmer. >> > >> > ? ? ? ?Optional parameters GET or SET (@property(GET) or >> > ? ? ? ?@property(SET)) would only attempt to generate the getter >> > ? ? ? ?or setter respectively. ?I don't think Java grammar would >> > ? ? ? ?be affected (?). >> > >> > ? ?Compilation: >> > ? ? ? ?Out of my depth here. ?The auto-generation feature *should* >> > ? ? ? ?be very straightforward as I would hope all the needed info >> > ? ? ? ?to create the getters/setters is available at compile-time. >> > ? ? ? ?I'm less clear on whether the compiler would be able to do >> > ? ? ? ?the auto-resolution so you could just use foo.age and >> > ? ? ? ?wouldn't be forced to call foo.getAge()/foo.setAge(), but >> > ? ? ? ?I'm hopeful this is also possible, as it would be a great >> > ? ? ? ?feature. >> > >> > ? ? ? ?This logic would have to support a hierarchy of resolution >> > ? ? ? ?so that if 'age' was a public ? ?data member then public >> > ? ? ? ?access would take precedence over trying to call the >> > ? ? ? ?accessor method. ?Likewise protected and private access >> > ? ? ? ?would take precedence over the getter if normal >> > ? ? ? ?visibility rules allowed this mode of access. >> > >> > ? ?Testing: >> > ? ? ? ?Hmm... >> > >> > ? ?Library Support: >> > ? ? ? ?Shouldn't require any library support >> > >> > ? ?Reflective APIs: >> > ? ? ? ?Existing APIs should be fine. ?The generated >> > ? ? ? ?getters/setters would be reflectively accessible since once >> > ? ? ? ?they are generated by the compiler they are no different >> > ? ? ? ?than if the programmer had written them. >> > >> > ? ?Other Changes: >> > ? ? ? ?None come to mine. >> > >> > ? ?Migration: >> > ? ? ? ?No conversion necessary. ?Normal getter/setter code in >> > ? ? ? ?common use today would still work and could live seamlessly >> > ? ? ? ?in parallel with code using the new features. >> > >> > COMPATIBILITY: >> > >> > ? ?Breaking Changes: >> > ? ? ? ?No code should break due to the changes proposed >> > >> > ? ?Existing Programs: >> > ? ? ? ?Existing code should live seamlessly in parallel to these >> > ? ? ? ?changes. ?If the compiler access precidence feature is >> > ? ? ? ?implemented then newly written code can take advantage of >> > ? ? ? ?this ability when calling existing unmodified code. ?For >> > ? ? ? ?example: >> > >> > ? ? ? ?// Existing code >> > ? ? ? ?public class Foo { >> > ? ? ? ? ? ?private int age; >> > ? ? ? ? ? ?public int getAge() { return this.age; } >> > ? ? ? ? ? ?public void setAge(int age) { this.age = age; } >> > ? ? ? ?} >> > >> > ? ? ? ?// New code >> > ? ? ? ?foo.age = 10; >> > >> > ? ? ? ?// compiler would first see if a public/protected/private >> > ? ? ? ?// visible age data member existed, and since there is none >> > ? ? ? ?// a call to getAge() would be inserted during compile time >> > ? ? ? ?// thus using the new feature to seamlessly interact with >> > ? ? ? ?// legacy code without altering semantics >> > >> > REFERENCES: >> > ? ?N/A >> > >> > >> > _________________________________________________________________ >> > Get free photo software from Windows Live >> > >> > >> http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL >> :en-US:SI_PH_software:082009 >> > >> > > > > -- ?? ?? From reinier at zwitserloot.com Sat Aug 15 19:51:01 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 16 Aug 2009 04:51:01 +0200 Subject: Annotations for language features (was: Re: A Late Entry) In-Reply-To: <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> Message-ID: <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> http://projectlombok.org/ is a prototype that lets you play around with what happens when you use annotations for language features. So far, the sky has not fallen down. On the contrary; they are namespaced and serve as document pointers, so they've been quite nice. Sure, it may not 'feel' right, but the sheer amount of backwards compatibility angst suggests to me that it's a shortcut worth thinking about - even when you are careful with the keyword string you pick and the keyword is made context sensitive, the impact is larger than an annotation. I'd certainly not presume that all, or even most, of the features discussed on coindev ought to be implemented with an annotation, but for a select few (including properties!) it makes sense to me. Consider for example making 'property' a context sensitive keyword. private final property String x; okay, but, lets say I have some old code that uses property as an identifier for a class. Yes, it breaks the camelcase rule, but its valid java. I'm going to be a little more evil, and I'm going to name this field 'String', again breaking the camelcase rule, but its still legal. That would look like: private final property String; Can we make the parser sort this out? --Reinier Zwitserloot Like it? Tip it! http://tipit.to On 2009/16/08, at 02:38, ?? wrote: > Hi, > > 2009/8/16 Ted Neward : >> Oh, but come on, Neal, everybody's doing it.... *cough* JSR 308 >> *cough* >> >> I'll be 100% honest: I'm really worried that 308 is going to open >> up a whole >> can of worms and people are going to do exactly that: create their >> own >> customized flavors of Java by using annotations to replace >> keywords. But >> that's for a different mailing list, I suppose. > > Agreed, but I not think it worth worried. Everyone have own flavors, > IMO tools author should not force others flavor. Of cause the code > with all flavors should work with each other, that just ok. > > back to the topic. > 1,Property annotation maybe no the best alternative. I agreed with > context-sensitive, through I'm fair even ten years after it still be a > future. > 2,The property proposal from based on field, I called it > B(ottom)2T(op) style. I talk a T2B style with Adam: property can be > focused on method and/or field, the field not must. some kind same as > JavaBean properties. most important, which is interface style. > >> Ted Neward >> Java, .NET, XML Services >> Consulting, Teaching, Speaking, Writing >> http://www.tedneward.com >> >>> -----Original Message----- >>> From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- >>> bounces at openjdk.java.net] On Behalf Of Neal Gafter >>> Sent: Sunday, August 09, 2009 11:22 AM >>> To: Greg Zoller >>> Cc: coin-dev at openjdk.java.net >>> Subject: Re: A Late Entry >>> >>> Annotations are not an appropriate "back door" for adding syntax >>> to the >>> Java >>> programming language. I suggest you instead consider context- >>> sensitive >>> keywords. >>> >>> On Sun, Aug 9, 2009 at 9:24 AM, Greg Zoller >>> wrote: >>> >>>> >>>> Members of coin-dev... I'm writing to submit a late proposal for >>>> the >>> Java >>>> language, if not for initial Java 7 release (probably too late) but >>> perhaps >>>> for a later release. Below is the proposal form. Plain text >>>> editor >>>> formatting is pretty inconsistent, so apologies if it looks poorly >>> formatted >>>> when you see it. >>>> >>>> >>>> Project Coin >>>> >>>> Late Submission: Hiding Accessors at Compile Time >>>> >>>> AUTHOR: Greg Zoller >>>> gzoller(atsign)hotmail.com >>>> >>>> OVERVIEW: >>>> >>>> Feature Summary: >>>> De-clutter classes littered with accessors by having the >>>> compiler auto-generate trivial accessors for data members >>>> denoted with a @property annotation. >>>> >>>> Major Advantage: >>>> Would eliminate lots (and lots) of messy get/set code >>>> without losing the benefits of having an accessor for the >>>> times you really need them. The proposed approach should >>>> not break any existing code not written to take advantage >>>> of the new capability. >>>> >>>> Major Benefit: >>>> Less cluttered code! Removes (or more specifically hides >>>> behind the compiler) the clumsy construct of accessors >>>> without losing the purpose and benfits of their existence. >>>> In other words, I want property accessor capability--I >>>> just don't want to see them! >>>> >>>> Major Disadvantage: >>>> None that come to mind--I'm sure someone will contribute a >>>> disadvantage. >>>> >>>> Alternatives: >>>> Leave things the way they are. >>>> >>>> EXAMPLES: >>>> >>>> /* Today */ >>>> public class Foo { >>>> private String name; // no accessors for name >>>> private int age; >>>> private double balance; >>>> private String comment; >>>> >>>> public int getAge() { return this.age; } >>>> public void setAge(int age) { this.age = age; } >>>> public double getBalance() { return this.balance; } >>>> public void setComment(String comment) { >>>> this.comment = comment; } >>>> } >>>> >>>> /* Proposed */ >>>> public class Foo { >>>> private String name; // no accessors generated >>>> @property private int age; // both get/set generated >>>> @property(GET) private double balance; // getter generated, >>> no >>>> setter >>>> @property(SET) private String comment; // setter generated, >>> no >>>> getter >>>> } >>>> >>>> // Code would use these properties via their generated >>>> // accessors as they do now: >>>> foo.setAge(foo.getAge() + 10); >>>> >>>> // EVEN BETTER... the compiler can try to resolve data member >>>> // access according to a scope/visibility hierarchy: >>>> // public member, protected member, private member, >>>> // inserted getter/setter call >>>> >>>> // If this can be done in the compiler then old code can still >>>> // call the accessors like always while new code could simply >>>> // have: >>>> >>>> foo.age += 10; >>>> System.out.println("Age: "+foo.age); >>>> >>>> // This looks as clean as direct data member access but age >>>> // remains private with all the benefits of having accessor >>>> // protection. In the example above assuming no public, >>>> // protected, or private visibility for age exists the compiler >>>> // will insert a call to foo.getAge() for the programmer if age >>>> // is a @property field (otherwise its a compile error). >>>> >>>> // NOTE: The compiler won't auto-generate a getter or setter if >>>> // one already has been specified by the programmer, allowing >>>> // full control like we have now: >>>> >>>> public class Foo { >>>> @property private int age; // only a trivial getter >>>> generated--setter exists >>>> public void setAge(int age) { >>>> msg.notify("Someone's tampering with age!"); >>>> this.age = age; >>>> } >>>> } >>>> >>>> // The compiler would exercise precedence logic in deciding >>>> // whether to insert a call to the accessors or not >>>> >>>> package A; >>>> public class Foo { >>>> @property private int age; // only setter generated--getter >>> exists >>>> public int getAge() { >>>> System.out.println("Getter called!"); >>>> return this.age; >>>> } >>>> public void something() { >>>> int anotherAge = this.age; >>>> // private visibility is valid--no compiler-inserted >>>> // call to this.getAge() here >>>> >>>> int oneMoreAge = this.getAge(); >>>> // explicit call to getter ok--just like today >>>> } >>>> } >>>> >>>> package B; >>>> public class Bar { >>>> public void blah(Foo foo) { >>>> System.out.println(foo.age); >>>> // Compiler can't resolve public, protected, or >>>> // private visibility to foo.age so a call to the >>>> // generated foo.getAge() accessor is inserted >>>> } >>>> } >>>> >>>> DETAILS >>>> >>>> Specification: >>>> Add the FIELD-targeted @property annotation to the >>>> language. Without parameters this will cause the >>>> generation of both a getter and setter unless one is >>>> already given by the programmer. >>>> >>>> Optional parameters GET or SET (@property(GET) or >>>> @property(SET)) would only attempt to generate the getter >>>> or setter respectively. I don't think Java grammar would >>>> be affected (?). >>>> >>>> Compilation: >>>> Out of my depth here. The auto-generation feature *should* >>>> be very straightforward as I would hope all the needed info >>>> to create the getters/setters is available at compile-time. >>>> I'm less clear on whether the compiler would be able to do >>>> the auto-resolution so you could just use foo.age and >>>> wouldn't be forced to call foo.getAge()/foo.setAge(), but >>>> I'm hopeful this is also possible, as it would be a great >>>> feature. >>>> >>>> This logic would have to support a hierarchy of resolution >>>> so that if 'age' was a public data member then public >>>> access would take precedence over trying to call the >>>> accessor method. Likewise protected and private access >>>> would take precedence over the getter if normal >>>> visibility rules allowed this mode of access. >>>> >>>> Testing: >>>> Hmm... >>>> >>>> Library Support: >>>> Shouldn't require any library support >>>> >>>> Reflective APIs: >>>> Existing APIs should be fine. The generated >>>> getters/setters would be reflectively accessible since once >>>> they are generated by the compiler they are no different >>>> than if the programmer had written them. >>>> >>>> Other Changes: >>>> None come to mine. >>>> >>>> Migration: >>>> No conversion necessary. Normal getter/setter code in >>>> common use today would still work and could live seamlessly >>>> in parallel with code using the new features. >>>> >>>> COMPATIBILITY: >>>> >>>> Breaking Changes: >>>> No code should break due to the changes proposed >>>> >>>> Existing Programs: >>>> Existing code should live seamlessly in parallel to these >>>> changes. If the compiler access precidence feature is >>>> implemented then newly written code can take advantage of >>>> this ability when calling existing unmodified code. For >>>> example: >>>> >>>> // Existing code >>>> public class Foo { >>>> private int age; >>>> public int getAge() { return this.age; } >>>> public void setAge(int age) { this.age = age; } >>>> } >>>> >>>> // New code >>>> foo.age = 10; >>>> >>>> // compiler would first see if a public/protected/private >>>> // visible age data member existed, and since there is none >>>> // a call to getAge() would be inserted during compile time >>>> // thus using the new feature to seamlessly interact with >>>> // legacy code without altering semantics >>>> >>>> REFERENCES: >>>> N/A >>>> >>>> >>>> _________________________________________________________________ >>>> Get free photo software from Windows Live >>>> >>>> >>> http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL >>> :en-US:SI_PH_software:082009 >>>> >>>> >> >> >> > > > > -- > ?? > ?? > From gzoller at hotmail.com Sat Aug 15 20:48:45 2009 From: gzoller at hotmail.com (Greg Zoller) Date: Sat, 15 Aug 2009 23:48:45 -0400 Subject: A Late Entry In-Reply-To: <03d301ca1dda$c55ccdb0$50166910$@com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> Message-ID: Really wasn't trying to open a debate on the relative merits of annotations vs. keywords--just wanted a good way to get rid of what (IMO) is a very messy convention of all those getters and setters, without losing the value they do provide. The reason I opted to think in terms of @property vs a new 'property' keyword was only because the way it was proposed it wasn't really a new language feature but rather a convenience at compile-time. Perhaps that's hair-splitting, but think in terms of a #pragma... just giving the compiler some direction to do some extra work for me on a purely optional basis (in other words programmers who opt not to use the feature suffer no loss of functionality). Of course keywords and structural change works fine too... just like the cleaned up for loop in jdk1.5. That didn't really add anything new to the language but it was a great modernization and clean-up that made coding that much nicer. Now that I think about it, perhaps a property keyword isn't bad at all. It would generate private-equiv bytecode on the data member and for the automatic access (implicit call to accessors) it should be easier since you know the field was declared a property--no messing with visibility/scope issues. All access anywhere goes through accessors, computer-generated and/or programmer supplied. property int foo; // accessors generated unless programmer already supplied them ... this.foo = 5; // compiler generates this.setFoo(5); Greg > From: ted at tedneward.com > To: neal at gafter.com; gzoller at hotmail.com > CC: coin-dev at openjdk.java.net > Subject: RE: A Late Entry > Date: Sat, 15 Aug 2009 12:01:16 -0700 > > Oh, but come on, Neal, everybody's doing it.... *cough* JSR 308 *cough* > > I'll be 100% honest: I'm really worried that 308 is going to open up a whole > can of worms and people are going to do exactly that: create their own > customized flavors of Java by using annotations to replace keywords. But > that's for a different mailing list, I suppose. > > Ted Neward > Java, .NET, XML Services > Consulting, Teaching, Speaking, Writing > http://www.tedneward.com > > > -----Original Message----- > > From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- > > bounces at openjdk.java.net] On Behalf Of Neal Gafter > > Sent: Sunday, August 09, 2009 11:22 AM > > To: Greg Zoller > > Cc: coin-dev at openjdk.java.net > > Subject: Re: A Late Entry > > > > Annotations are not an appropriate "back door" for adding syntax to the > > Java > > programming language. I suggest you instead consider context-sensitive > > keywords. > > > > On Sun, Aug 9, 2009 at 9:24 AM, Greg Zoller > > wrote: > > > > > > > > Members of coin-dev... I'm writing to submit a late proposal for the > > Java > > > language, if not for initial Java 7 release (probably too late) but > > perhaps > > > for a later release. Below is the proposal form. Plain text editor > > > formatting is pretty inconsistent, so apologies if it looks poorly > > formatted > > > when you see it. > > > > > > > > > Project Coin > > > > > > Late Submission: Hiding Accessors at Compile Time > > > > > > AUTHOR: Greg Zoller > > > gzoller(atsign)hotmail.com > > > > > > OVERVIEW: > > > > > > Feature Summary: > > > De-clutter classes littered with accessors by having the > > > compiler auto-generate trivial accessors for data members > > > denoted with a @property annotation. > > > > > > Major Advantage: > > > Would eliminate lots (and lots) of messy get/set code > > > without losing the benefits of having an accessor for the > > > times you really need them. The proposed approach should > > > not break any existing code not written to take advantage > > > of the new capability. > > > > > > Major Benefit: > > > Less cluttered code! Removes (or more specifically hides > > > behind the compiler) the clumsy construct of accessors > > > without losing the purpose and benfits of their existence. > > > In other words, I want property accessor capability--I > > > just don't want to see them! > > > > > > Major Disadvantage: > > > None that come to mind--I'm sure someone will contribute a > > > disadvantage. > > > > > > Alternatives: > > > Leave things the way they are. > > > > > > EXAMPLES: > > > > > > /* Today */ > > > public class Foo { > > > private String name; // no accessors for name > > > private int age; > > > private double balance; > > > private String comment; > > > > > > public int getAge() { return this.age; } > > > public void setAge(int age) { this.age = age; } > > > public double getBalance() { return this.balance; } > > > public void setComment(String comment) { > > > this.comment = comment; } > > > } > > > > > > /* Proposed */ > > > public class Foo { > > > private String name; // no accessors generated > > > @property private int age; // both get/set generated > > > @property(GET) private double balance; // getter generated, > > no > > > setter > > > @property(SET) private String comment; // setter generated, > > no > > > getter > > > } > > > > > > // Code would use these properties via their generated > > > // accessors as they do now: > > > foo.setAge(foo.getAge() + 10); > > > > > > // EVEN BETTER... the compiler can try to resolve data member > > > // access according to a scope/visibility hierarchy: > > > // public member, protected member, private member, > > > // inserted getter/setter call > > > > > > // If this can be done in the compiler then old code can still > > > // call the accessors like always while new code could simply > > > // have: > > > > > > foo.age += 10; > > > System.out.println("Age: "+foo.age); > > > > > > // This looks as clean as direct data member access but age > > > // remains private with all the benefits of having accessor > > > // protection. In the example above assuming no public, > > > // protected, or private visibility for age exists the compiler > > > // will insert a call to foo.getAge() for the programmer if age > > > // is a @property field (otherwise its a compile error). > > > > > > // NOTE: The compiler won't auto-generate a getter or setter if > > > // one already has been specified by the programmer, allowing > > > // full control like we have now: > > > > > > public class Foo { > > > @property private int age; // only a trivial getter > > > generated--setter exists > > > public void setAge(int age) { > > > msg.notify("Someone's tampering with age!"); > > > this.age = age; > > > } > > > } > > > > > > // The compiler would exercise precedence logic in deciding > > > // whether to insert a call to the accessors or not > > > > > > package A; > > > public class Foo { > > > @property private int age; // only setter generated--getter > > exists > > > public int getAge() { > > > System.out.println("Getter called!"); > > > return this.age; > > > } > > > public void something() { > > > int anotherAge = this.age; > > > // private visibility is valid--no compiler-inserted > > > // call to this.getAge() here > > > > > > int oneMoreAge = this.getAge(); > > > // explicit call to getter ok--just like today > > > } > > > } > > > > > > package B; > > > public class Bar { > > > public void blah(Foo foo) { > > > System.out.println(foo.age); > > > // Compiler can't resolve public, protected, or > > > // private visibility to foo.age so a call to the > > > // generated foo.getAge() accessor is inserted > > > } > > > } > > > > > > DETAILS > > > > > > Specification: > > > Add the FIELD-targeted @property annotation to the > > > language. Without parameters this will cause the > > > generation of both a getter and setter unless one is > > > already given by the programmer. > > > > > > Optional parameters GET or SET (@property(GET) or > > > @property(SET)) would only attempt to generate the getter > > > or setter respectively. I don't think Java grammar would > > > be affected (?). > > > > > > Compilation: > > > Out of my depth here. The auto-generation feature *should* > > > be very straightforward as I would hope all the needed info > > > to create the getters/setters is available at compile-time. > > > I'm less clear on whether the compiler would be able to do > > > the auto-resolution so you could just use foo.age and > > > wouldn't be forced to call foo.getAge()/foo.setAge(), but > > > I'm hopeful this is also possible, as it would be a great > > > feature. > > > > > > This logic would have to support a hierarchy of resolution > > > so that if 'age' was a public data member then public > > > access would take precedence over trying to call the > > > accessor method. Likewise protected and private access > > > would take precedence over the getter if normal > > > visibility rules allowed this mode of access. > > > > > > Testing: > > > Hmm... > > > > > > Library Support: > > > Shouldn't require any library support > > > > > > Reflective APIs: > > > Existing APIs should be fine. The generated > > > getters/setters would be reflectively accessible since once > > > they are generated by the compiler they are no different > > > than if the programmer had written them. > > > > > > Other Changes: > > > None come to mine. > > > > > > Migration: > > > No conversion necessary. Normal getter/setter code in > > > common use today would still work and could live seamlessly > > > in parallel with code using the new features. > > > > > > COMPATIBILITY: > > > > > > Breaking Changes: > > > No code should break due to the changes proposed > > > > > > Existing Programs: > > > Existing code should live seamlessly in parallel to these > > > changes. If the compiler access precidence feature is > > > implemented then newly written code can take advantage of > > > this ability when calling existing unmodified code. For > > > example: > > > > > > // Existing code > > > public class Foo { > > > private int age; > > > public int getAge() { return this.age; } > > > public void setAge(int age) { this.age = age; } > > > } > > > > > > // New code > > > foo.age = 10; > > > > > > // compiler would first see if a public/protected/private > > > // visible age data member existed, and since there is none > > > // a call to getAge() would be inserted during compile time > > > // thus using the new feature to seamlessly interact with > > > // legacy code without altering semantics > > > > > > REFERENCES: > > > N/A > > > > > > > > > _________________________________________________________________ > > > Get free photo software from Windows Live > > > > > > > > http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL > > :en-US:SI_PH_software:082009 > > > > > > > _________________________________________________________________ Windows Live?: Keep your life in sync. http://windowslive.com/explore?ocid=PID23384::T:WLMTAGL:ON:WL:en-US:NF_BR_sync:082009 From ted at tedneward.com Sat Aug 15 22:58:28 2009 From: ted at tedneward.com (Ted Neward) Date: Sat, 15 Aug 2009 22:58:28 -0700 Subject: Annotations for language features (was: Re: A Late Entry) In-Reply-To: <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> Message-ID: <042d01ca1e36$97733ea0$c659bbe0$@com> I think I missed a few steps here. > okay, but, lets say I have some old code that uses property as an > identifier for a class. Yes, it breaks the camelcase rule, but its > valid java. I'm going to be a little more evil, and I'm going to name > this field 'String', again breaking the camelcase rule, but its still > legal. That would look like: > > private final property String; > > Can we make the parser sort this out? > How about even if we can't, we just say that because you named a field after a class name (and a popular one at that), you're an idiot and your code breaks until you fix being an idiot? In this case, it consists of a single refactoring. Problem solved, for that idiot, anyway. Seriously, I think we've been tiptoeing around the "Java language code will break" issue for far too long. The .class files are compatible (and even where they're not, they're tagged with a version number so at least we can know what version they target, *and* the JDK is reasonably easy to obtain and upgrade), so let's just bring Java into the 21st century and make them fully-fledged members of the keyword society. Yes, I remember how the community howled when Java 1.4 "broke" JUnit. But the community howls no matter what you do, so screw 'em. Do what's right, not what's popular. Instead of playing games that create more edge cases than useful features, let's just rev the language, call it "Java 2.0", and go from there. The .class file format doesn't have to change for most of these, so I fail to see what the major issues are here. My $.02 worth, anyway. Ted Neward Java, .NET, XML Services Consulting, Teaching, Speaking, Writing http://www.tedneward.com > -----Original Message----- > From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- > bounces at openjdk.java.net] On Behalf Of Reinier Zwitserloot > Sent: Saturday, August 15, 2009 7:51 PM > To: coin-dev at openjdk.java.net > Subject: Annotations for language features (was: Re: A Late Entry) > > http://projectlombok.org/ is a prototype that lets you play around > with what happens when you use annotations for language features. > > So far, the sky has not fallen down. On the contrary; they are > namespaced and serve as document pointers, so they've been quite nice. > > > Sure, it may not 'feel' right, but the sheer amount of backwards > compatibility angst suggests to me that it's a shortcut worth thinking > about - even when you are careful with the keyword string you pick and > the keyword is made context sensitive, the impact is larger than an > annotation. I'd certainly not presume that all, or even most, of the > features discussed on coindev ought to be implemented with an > annotation, but for a select few (including properties!) it makes > sense to me. > > Consider for example making 'property' a context sensitive keyword. > > private final property String x; > > okay, but, lets say I have some old code that uses property as an > identifier for a class. Yes, it breaks the camelcase rule, but its > valid java. I'm going to be a little more evil, and I'm going to name > this field 'String', again breaking the camelcase rule, but its still > legal. That would look like: > > private final property String; > > Can we make the parser sort this out? > > > > > --Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > > > On 2009/16/08, at 02:38, ?? wrote: > > > Hi, > > > > 2009/8/16 Ted Neward : > >> Oh, but come on, Neal, everybody's doing it.... *cough* JSR 308 > >> *cough* > >> > >> I'll be 100% honest: I'm really worried that 308 is going to open > >> up a whole > >> can of worms and people are going to do exactly that: create their > >> own > >> customized flavors of Java by using annotations to replace > >> keywords. But > >> that's for a different mailing list, I suppose. > > > > Agreed, but I not think it worth worried. Everyone have own flavors, > > IMO tools author should not force others flavor. Of cause the code > > with all flavors should work with each other, that just ok. > > > > back to the topic. > > 1,Property annotation maybe no the best alternative. I agreed with > > context-sensitive, through I'm fair even ten years after it still be > a > > future. > > 2,The property proposal from based on field, I called it > > B(ottom)2T(op) style. I talk a T2B style with Adam: property can be > > focused on method and/or field, the field not must. some kind same as > > JavaBean properties. most important, which is interface style. > > > >> Ted Neward > >> Java, .NET, XML Services > >> Consulting, Teaching, Speaking, Writing > >> http://www.tedneward.com > >> > >>> -----Original Message----- > >>> From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- > >>> bounces at openjdk.java.net] On Behalf Of Neal Gafter > >>> Sent: Sunday, August 09, 2009 11:22 AM > >>> To: Greg Zoller > >>> Cc: coin-dev at openjdk.java.net > >>> Subject: Re: A Late Entry > >>> > >>> Annotations are not an appropriate "back door" for adding syntax > >>> to the > >>> Java > >>> programming language. I suggest you instead consider context- > >>> sensitive > >>> keywords. > >>> > >>> On Sun, Aug 9, 2009 at 9:24 AM, Greg Zoller > >>> wrote: > >>> > >>>> > >>>> Members of coin-dev... I'm writing to submit a late proposal for > >>>> the > >>> Java > >>>> language, if not for initial Java 7 release (probably too late) > but > >>> perhaps > >>>> for a later release. Below is the proposal form. Plain text > >>>> editor > >>>> formatting is pretty inconsistent, so apologies if it looks poorly > >>> formatted > >>>> when you see it. > >>>> > >>>> > >>>> Project Coin > >>>> > >>>> Late Submission: Hiding Accessors at Compile Time > >>>> > >>>> AUTHOR: Greg Zoller > >>>> gzoller(atsign)hotmail.com > >>>> > >>>> OVERVIEW: > >>>> > >>>> Feature Summary: > >>>> De-clutter classes littered with accessors by having the > >>>> compiler auto-generate trivial accessors for data members > >>>> denoted with a @property annotation. > >>>> > >>>> Major Advantage: > >>>> Would eliminate lots (and lots) of messy get/set code > >>>> without losing the benefits of having an accessor for the > >>>> times you really need them. The proposed approach should > >>>> not break any existing code not written to take advantage > >>>> of the new capability. > >>>> > >>>> Major Benefit: > >>>> Less cluttered code! Removes (or more specifically hides > >>>> behind the compiler) the clumsy construct of accessors > >>>> without losing the purpose and benfits of their existence. > >>>> In other words, I want property accessor capability--I > >>>> just don't want to see them! > >>>> > >>>> Major Disadvantage: > >>>> None that come to mind--I'm sure someone will contribute a > >>>> disadvantage. > >>>> > >>>> Alternatives: > >>>> Leave things the way they are. > >>>> > >>>> EXAMPLES: > >>>> > >>>> /* Today */ > >>>> public class Foo { > >>>> private String name; // no accessors for name > >>>> private int age; > >>>> private double balance; > >>>> private String comment; > >>>> > >>>> public int getAge() { return this.age; } > >>>> public void setAge(int age) { this.age = age; } > >>>> public double getBalance() { return this.balance; } > >>>> public void setComment(String comment) { > >>>> this.comment = comment; } > >>>> } > >>>> > >>>> /* Proposed */ > >>>> public class Foo { > >>>> private String name; // no accessors generated > >>>> @property private int age; // both get/set generated > >>>> @property(GET) private double balance; // getter > generated, > >>> no > >>>> setter > >>>> @property(SET) private String comment; // setter > generated, > >>> no > >>>> getter > >>>> } > >>>> > >>>> // Code would use these properties via their generated > >>>> // accessors as they do now: > >>>> foo.setAge(foo.getAge() + 10); > >>>> > >>>> // EVEN BETTER... the compiler can try to resolve data member > >>>> // access according to a scope/visibility hierarchy: > >>>> // public member, protected member, private member, > >>>> // inserted getter/setter call > >>>> > >>>> // If this can be done in the compiler then old code can still > >>>> // call the accessors like always while new code could simply > >>>> // have: > >>>> > >>>> foo.age += 10; > >>>> System.out.println("Age: "+foo.age); > >>>> > >>>> // This looks as clean as direct data member access but age > >>>> // remains private with all the benefits of having accessor > >>>> // protection. In the example above assuming no public, > >>>> // protected, or private visibility for age exists the compiler > >>>> // will insert a call to foo.getAge() for the programmer if age > >>>> // is a @property field (otherwise its a compile error). > >>>> > >>>> // NOTE: The compiler won't auto-generate a getter or setter > if > >>>> // one already has been specified by the programmer, allowing > >>>> // full control like we have now: > >>>> > >>>> public class Foo { > >>>> @property private int age; // only a trivial getter > >>>> generated--setter exists > >>>> public void setAge(int age) { > >>>> msg.notify("Someone's tampering with age!"); > >>>> this.age = age; > >>>> } > >>>> } > >>>> > >>>> // The compiler would exercise precedence logic in deciding > >>>> // whether to insert a call to the accessors or not > >>>> > >>>> package A; > >>>> public class Foo { > >>>> @property private int age; // only setter generated-- > getter > >>> exists > >>>> public int getAge() { > >>>> System.out.println("Getter called!"); > >>>> return this.age; > >>>> } > >>>> public void something() { > >>>> int anotherAge = this.age; > >>>> // private visibility is valid--no compiler-inserted > >>>> // call to this.getAge() here > >>>> > >>>> int oneMoreAge = this.getAge(); > >>>> // explicit call to getter ok--just like today > >>>> } > >>>> } > >>>> > >>>> package B; > >>>> public class Bar { > >>>> public void blah(Foo foo) { > >>>> System.out.println(foo.age); > >>>> // Compiler can't resolve public, protected, or > >>>> // private visibility to foo.age so a call to the > >>>> // generated foo.getAge() accessor is inserted > >>>> } > >>>> } > >>>> > >>>> DETAILS > >>>> > >>>> Specification: > >>>> Add the FIELD-targeted @property annotation to the > >>>> language. Without parameters this will cause the > >>>> generation of both a getter and setter unless one is > >>>> already given by the programmer. > >>>> > >>>> Optional parameters GET or SET (@property(GET) or > >>>> @property(SET)) would only attempt to generate the getter > >>>> or setter respectively. I don't think Java grammar would > >>>> be affected (?). > >>>> > >>>> Compilation: > >>>> Out of my depth here. The auto-generation feature *should* > >>>> be very straightforward as I would hope all the needed info > >>>> to create the getters/setters is available at compile-time. > >>>> I'm less clear on whether the compiler would be able to do > >>>> the auto-resolution so you could just use foo.age and > >>>> wouldn't be forced to call foo.getAge()/foo.setAge(), but > >>>> I'm hopeful this is also possible, as it would be a great > >>>> feature. > >>>> > >>>> This logic would have to support a hierarchy of resolution > >>>> so that if 'age' was a public data member then public > >>>> access would take precedence over trying to call the > >>>> accessor method. Likewise protected and private access > >>>> would take precedence over the getter if normal > >>>> visibility rules allowed this mode of access. > >>>> > >>>> Testing: > >>>> Hmm... > >>>> > >>>> Library Support: > >>>> Shouldn't require any library support > >>>> > >>>> Reflective APIs: > >>>> Existing APIs should be fine. The generated > >>>> getters/setters would be reflectively accessible since once > >>>> they are generated by the compiler they are no different > >>>> than if the programmer had written them. > >>>> > >>>> Other Changes: > >>>> None come to mine. > >>>> > >>>> Migration: > >>>> No conversion necessary. Normal getter/setter code in > >>>> common use today would still work and could live seamlessly > >>>> in parallel with code using the new features. > >>>> > >>>> COMPATIBILITY: > >>>> > >>>> Breaking Changes: > >>>> No code should break due to the changes proposed > >>>> > >>>> Existing Programs: > >>>> Existing code should live seamlessly in parallel to these > >>>> changes. If the compiler access precidence feature is > >>>> implemented then newly written code can take advantage of > >>>> this ability when calling existing unmodified code. For > >>>> example: > >>>> > >>>> // Existing code > >>>> public class Foo { > >>>> private int age; > >>>> public int getAge() { return this.age; } > >>>> public void setAge(int age) { this.age = age; } > >>>> } > >>>> > >>>> // New code > >>>> foo.age = 10; > >>>> > >>>> // compiler would first see if a public/protected/private > >>>> // visible age data member existed, and since there is none > >>>> // a call to getAge() would be inserted during compile time > >>>> // thus using the new feature to seamlessly interact with > >>>> // legacy code without altering semantics > >>>> > >>>> REFERENCES: > >>>> N/A > >>>> > >>>> > >>>> _________________________________________________________________ > >>>> Get free photo software from Windows Live > >>>> > >>>> > >>> > http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL > >>> :en-US:SI_PH_software:082009 > >>>> > >>>> > >> > >> > >> > > > > > > > > -- > > ?? > > ?? > > > From abies at adres.pl Sun Aug 16 01:03:16 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Sun, 16 Aug 2009 10:03:16 +0200 Subject: Annotations for language features In-Reply-To: <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> Message-ID: <4A87BD44.4060406@adres.pl> Reinier Zwitserloot wrote: > http://projectlombok.org/ is a prototype that lets you play around > with what happens when you use annotations for language features. > > So far, the sky has not fallen down. On the contrary; they are > namespaced and serve as document pointers, so they've been quite nice. > For me, rule of thumb is: if you remove all properties from the source code (everywhere, libraries and user code), code should still compile. It can fail only on runtime and only because somebody is explicitly using reflection to retrieve annotations. So far, all official annotations and all proposed ones follow this rule. Even JSR 308 is the same - type annotations are optional, meaning that if you would remove them from std lib and your code, everything would compile properly. Project lombok is interesting hack, but I would never, ever like to see it happening to official java. Next step and we will end up Borland Pascal way and put control instructions in comments/javadoc. With best regards, Artur Biesiadowski From fyaoxy at gmail.com Sun Aug 16 03:12:30 2009 From: fyaoxy at gmail.com (=?UTF-8?B?5ZCR6ZuF?=) Date: Sun, 16 Aug 2009 18:12:30 +0800 Subject: Annotations for language features (was: Re: A Late Entry) In-Reply-To: <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> Message-ID: <91dd9a4f0908160312l612c0e29y53112f89b0a91264@mail.gmail.com> I have follows points: 1, annotations, Yes, lombok demo, check package, and so on, proved Annotation is good way to handle other aspects. Maybe more annotation about compiler syntax and flavors is better. Every one flavor his flavor. 2, backwords compatible, IMO, it should not be a barrier for developing(not development). There are so many languages, that self is a existed proof. And annother instance, MS, release new languages, compatible just a little consideration. Tf compatible compatible, if not not, which not care. so maybe a real Java2 should shine, forgot compatible. I feel the arguments abount language somehow like USA politics. Have this need? 3, context sensitive, Nowday, little or not, most language contains some senstive features, through just some special processes. Maybe english self is barrier on the context sensitve way, which tradition is state in all details instead of very context sensitive. I mean not character. Yes, now almost computer language think in english style or same style. (But seems the languagist not much more intrest in compute science, wonder!) So have a ten-years-after speaking in before message. I contributed a project on.dev.java.net, which is context sentive object model notation. I like it, of cause I like it:) If context sensitived, a real Java2 will out with no doubt. 4, the proerty String sample 4.1, private final property String x, We often state the property is a public property. so: MAYBE just type: property String x; 4.2, private final property String x; private final property String; In the context, the are ways to recog it. f.e. priority style, warning style, max-allow style. For "private final property String", maybe a compiler can warning use a keyword as type, another compiler complain cannot find property class. 5, the property construction CORBA idl support property, but seems not so whole. If describe an object, or thing, We do real often refer its public properties or attributes. Static object or thing, its properties maybe static. Dynamic object or thing, such as man, its properties maybe dynamic. f.e. aMan.old=? And the property cannot replace the field. Property may depend on the inner field, may not. So a property declaration, should contains three parts: propertyType, propertyName, propertyImplementation. Indeed, JavaBean do a same thing, through not so whole, which implementation just focused or defined at methods. Compare to C#, field style property supported. 2009/8/16 Reinier Zwitserloot : > http://projectlombok.org/ is a prototype that lets you play around > with what happens when you use annotations for language features. > > So far, the sky has not fallen down. On the contrary; they are > namespaced and serve as document pointers, so they've been quite nice. > > > Sure, it may not 'feel' right, but the sheer amount of backwards > compatibility angst suggests to me that it's a shortcut worth thinking > about - even when you are careful with the keyword string you pick and > the keyword is made context sensitive, the impact is larger than an > annotation. I'd certainly not presume that all, or even most, of the > features discussed on coindev ought to be implemented with an > annotation, but for a select few (including properties!) it makes > sense to me. > > Consider for example making 'property' a context sensitive keyword. > > private final property String x; > > okay, but, lets say I have some old code that uses property as an > identifier for a class. Yes, it breaks the camelcase rule, but its > valid java. I'm going to be a little more evil, and I'm going to name > this field 'String', again breaking the camelcase rule, but its still > legal. That would look like: > > private final property String; > > Can we make the parser sort this out? > > > > > ?--Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > > > On 2009/16/08, at 02:38, ?? wrote: > >> Hi, >> >> 2009/8/16 Ted Neward : >>> Oh, but come on, Neal, everybody's doing it.... *cough* JSR 308 >>> *cough* >>> >>> I'll be 100% honest: I'm really worried that 308 is going to open >>> up a whole >>> can of worms and people are going to do exactly that: create their >>> own >>> customized flavors of Java by using annotations to replace >>> keywords. But >>> that's for a different mailing list, I suppose. >> >> Agreed, but I not think it worth worried. Everyone have own flavors, >> IMO tools author should not force others flavor. Of cause the code >> with all flavors should work with each other, that just ok. >> >> back to the topic. >> 1,Property annotation maybe no the best alternative. I agreed with >> context-sensitive, through I'm fair even ten years after it still be a >> future. >> 2,The property proposal from based on field, I called it >> B(ottom)2T(op) style. I talk a T2B style with Adam: property can be >> focused on method and/or field, the field not must. some kind same as >> JavaBean properties. most important, which is interface style. >> >>> Ted Neward >>> Java, .NET, XML Services >>> Consulting, Teaching, Speaking, Writing >>> http://www.tedneward.com >>> >>>> -----Original Message----- >>>> From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- >>>> bounces at openjdk.java.net] On Behalf Of Neal Gafter >>>> Sent: Sunday, August 09, 2009 11:22 AM >>>> To: Greg Zoller >>>> Cc: coin-dev at openjdk.java.net >>>> Subject: Re: A Late Entry >>>> >>>> Annotations are not an appropriate "back door" for adding syntax >>>> to the >>>> Java >>>> programming language. ?I suggest you instead consider context- >>>> sensitive >>>> keywords. >>>> >>>> On Sun, Aug 9, 2009 at 9:24 AM, Greg Zoller >>>> wrote: >>>> >>>>> >>>>> Members of coin-dev... ?I'm writing to submit a late proposal for >>>>> the >>>> Java >>>>> language, if not for initial Java 7 release (probably too late) but >>>> perhaps >>>>> for a later release. ?Below is the proposal form. ?Plain text >>>>> editor >>>>> formatting is pretty inconsistent, so apologies if it looks poorly >>>> formatted >>>>> when you see it. >>>>> >>>>> >>>>> Project Coin >>>>> >>>>> Late Submission: Hiding Accessors at Compile Time >>>>> >>>>> AUTHOR: ?Greg Zoller >>>>> ? ? ? ? gzoller(atsign)hotmail.com >>>>> >>>>> OVERVIEW: >>>>> >>>>> ? ?Feature Summary: >>>>> ? ? ? ?De-clutter classes littered with accessors by having the >>>>> ? ? ? ?compiler auto-generate trivial accessors for data members >>>>> ? ? ? ?denoted with a @property annotation. >>>>> >>>>> ? ?Major Advantage: >>>>> ? ? ? ?Would eliminate lots (and lots) of messy get/set code >>>>> ? ? ? ?without losing the benefits of having an accessor for the >>>>> ? ? ? ?times you really need them. ?The proposed approach should >>>>> ? ? ? ?not break any existing code not written to take advantage >>>>> ? ? ? ?of the new capability. >>>>> >>>>> ? ?Major Benefit: >>>>> ? ? ? ?Less cluttered code! ?Removes (or more specifically hides >>>>> ? ? ? ?behind the compiler) the clumsy construct of accessors >>>>> ? ? ? ?without losing the purpose and benfits of their existence. >>>>> ? ? ? ?In other words, I want property accessor capability--I >>>>> ? ? ? ?just don't want to see them! >>>>> >>>>> ? ?Major Disadvantage: >>>>> ? ? ? ?None that come to mind--I'm sure someone will contribute a >>>>> ? ? ? ?disadvantage. >>>>> >>>>> ? ?Alternatives: >>>>> ? ? ? ?Leave things the way they are. >>>>> >>>>> EXAMPLES: >>>>> >>>>> ? ?/* Today */ >>>>> ? ?public class Foo { >>>>> ? ? ? ?private String name; ?// no accessors for name >>>>> ? ? ? ?private int age; >>>>> ? ? ? ?private double balance; >>>>> ? ? ? ?private String comment; >>>>> >>>>> ? ? ? ?public int getAge() { return this.age; } >>>>> ? ? ? ?public void setAge(int age) { this.age = age; } >>>>> ? ? ? ?public double getBalance() { return this.balance; } >>>>> ? ? ? ?public void setComment(String comment) { >>>>> ? ? ? ? ? ?this.comment = comment; } >>>>> ? ?} >>>>> >>>>> ? ?/* Proposed */ >>>>> ? ?public class Foo { >>>>> ? ? ? ?private String name; ?// no accessors generated >>>>> ? ? ? ?@property private int age; ?// both get/set generated >>>>> ? ? ? ?@property(GET) private double balance; ?// getter generated, >>>> no >>>>> setter >>>>> ? ? ? ?@property(SET) private String comment; ?// setter generated, >>>> no >>>>> getter >>>>> ? ?} >>>>> >>>>> ? ?// Code would use these properties via their generated >>>>> ? ?// accessors as they do now: >>>>> ? ?foo.setAge(foo.getAge() + 10); >>>>> >>>>> ? ?// EVEN BETTER... the compiler can try to resolve data member >>>>> ? ?// access according to a scope/visibility hierarchy: >>>>> ? ?// ? ? ? public member, protected member, private member, >>>>> ? ?// ? ? ? inserted getter/setter call >>>>> >>>>> ? ?// If this can be done in the compiler then old code can still >>>>> ? ?// call the accessors like always while new code could simply >>>>> ? ?// have: >>>>> >>>>> ? ?foo.age += 10; >>>>> ? ?System.out.println("Age: "+foo.age); >>>>> >>>>> ? ?// This looks as clean as direct data member access but age >>>>> ? ?// remains private with all the benefits of having accessor >>>>> ? ?// protection. ?In the example above assuming no public, >>>>> ? ?// protected, or private visibility for age exists the compiler >>>>> ? ?// will insert a call to foo.getAge() for the programmer if age >>>>> ? ?// is a @property field (otherwise its a compile error). >>>>> >>>>> ? ?// NOTE: ?The compiler won't auto-generate a getter or setter if >>>>> ? ?// one already has been specified by the programmer, allowing >>>>> ? ?// full control like we have now: >>>>> >>>>> ? ?public class Foo { >>>>> ? ? ? ?@property private int age; ?// only a trivial getter >>>>> generated--setter exists >>>>> ? ? ? ?public void setAge(int age) { >>>>> ? ? ? ? ? ?msg.notify("Someone's tampering with age!"); >>>>> ? ? ? ? ? ?this.age = age; >>>>> ? ? ? ?} >>>>> ? ?} >>>>> >>>>> ? ?// The compiler would exercise precedence logic in deciding >>>>> ? ?// whether to insert a call to the accessors or not >>>>> >>>>> ? ?package A; >>>>> ? ?public class Foo { >>>>> ? ? ? ?@property private int age; ?// only setter generated--getter >>>> exists >>>>> ? ? ? ?public int getAge() { >>>>> ? ? ? ? ? ?System.out.println("Getter called!"); >>>>> ? ? ? ? ? ?return this.age; >>>>> ? ? ? ?} >>>>> ? ? ? ?public void something() { >>>>> ? ? ? ? ? ?int anotherAge = this.age; >>>>> ? ? ? ? ? ?// private visibility is valid--no compiler-inserted >>>>> ? ? ? ? ? ?// call to this.getAge() here >>>>> >>>>> ? ? ? ? ? ?int oneMoreAge = this.getAge(); >>>>> ? ? ? ? ? ?// explicit call to getter ok--just like today >>>>> ? ? ? ?} >>>>> ? ?} >>>>> >>>>> ? ?package B; >>>>> ? ?public class Bar { >>>>> ? ? ? ?public void blah(Foo foo) { >>>>> ? ? ? ? ? ?System.out.println(foo.age); >>>>> ? ? ? ? ? ?// Compiler can't resolve public, protected, or >>>>> ? ? ? ? ? ?// private visibility to foo.age so a call to the >>>>> ? ? ? ? ? ?// generated foo.getAge() accessor is inserted >>>>> ? ? ? ?} >>>>> ? ?} >>>>> >>>>> DETAILS >>>>> >>>>> ? ?Specification: >>>>> ? ? ? ?Add the FIELD-targeted @property annotation to the >>>>> ? ? ? ?language. ?Without parameters this will cause the >>>>> ? ? ? ?generation of both a getter and setter unless one is >>>>> ? ? ? ?already given by the programmer. >>>>> >>>>> ? ? ? ?Optional parameters GET or SET (@property(GET) or >>>>> ? ? ? ?@property(SET)) would only attempt to generate the getter >>>>> ? ? ? ?or setter respectively. ?I don't think Java grammar would >>>>> ? ? ? ?be affected (?). >>>>> >>>>> ? ?Compilation: >>>>> ? ? ? ?Out of my depth here. ?The auto-generation feature *should* >>>>> ? ? ? ?be very straightforward as I would hope all the needed info >>>>> ? ? ? ?to create the getters/setters is available at compile-time. >>>>> ? ? ? ?I'm less clear on whether the compiler would be able to do >>>>> ? ? ? ?the auto-resolution so you could just use foo.age and >>>>> ? ? ? ?wouldn't be forced to call foo.getAge()/foo.setAge(), but >>>>> ? ? ? ?I'm hopeful this is also possible, as it would be a great >>>>> ? ? ? ?feature. >>>>> >>>>> ? ? ? ?This logic would have to support a hierarchy of resolution >>>>> ? ? ? ?so that if 'age' was a public ? ?data member then public >>>>> ? ? ? ?access would take precedence over trying to call the >>>>> ? ? ? ?accessor method. ?Likewise protected and private access >>>>> ? ? ? ?would take precedence over the getter if normal >>>>> ? ? ? ?visibility rules allowed this mode of access. >>>>> >>>>> ? ?Testing: >>>>> ? ? ? ?Hmm... >>>>> >>>>> ? ?Library Support: >>>>> ? ? ? ?Shouldn't require any library support >>>>> >>>>> ? ?Reflective APIs: >>>>> ? ? ? ?Existing APIs should be fine. ?The generated >>>>> ? ? ? ?getters/setters would be reflectively accessible since once >>>>> ? ? ? ?they are generated by the compiler they are no different >>>>> ? ? ? ?than if the programmer had written them. >>>>> >>>>> ? ?Other Changes: >>>>> ? ? ? ?None come to mine. >>>>> >>>>> ? ?Migration: >>>>> ? ? ? ?No conversion necessary. ?Normal getter/setter code in >>>>> ? ? ? ?common use today would still work and could live seamlessly >>>>> ? ? ? ?in parallel with code using the new features. >>>>> >>>>> COMPATIBILITY: >>>>> >>>>> ? ?Breaking Changes: >>>>> ? ? ? ?No code should break due to the changes proposed >>>>> >>>>> ? ?Existing Programs: >>>>> ? ? ? ?Existing code should live seamlessly in parallel to these >>>>> ? ? ? ?changes. ?If the compiler access precidence feature is >>>>> ? ? ? ?implemented then newly written code can take advantage of >>>>> ? ? ? ?this ability when calling existing unmodified code. ?For >>>>> ? ? ? ?example: >>>>> >>>>> ? ? ? ?// Existing code >>>>> ? ? ? ?public class Foo { >>>>> ? ? ? ? ? ?private int age; >>>>> ? ? ? ? ? ?public int getAge() { return this.age; } >>>>> ? ? ? ? ? ?public void setAge(int age) { this.age = age; } >>>>> ? ? ? ?} >>>>> >>>>> ? ? ? ?// New code >>>>> ? ? ? ?foo.age = 10; >>>>> >>>>> ? ? ? ?// compiler would first see if a public/protected/private >>>>> ? ? ? ?// visible age data member existed, and since there is none >>>>> ? ? ? ?// a call to getAge() would be inserted during compile time >>>>> ? ? ? ?// thus using the new feature to seamlessly interact with >>>>> ? ? ? ?// legacy code without altering semantics >>>>> >>>>> REFERENCES: >>>>> ? ?N/A >>>>> >>>>> >>>>> _________________________________________________________________ >>>>> Get free photo software from Windows Live >>>>> >>>>> >>>> http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL >>>> :en-US:SI_PH_software:082009 >>>>> >>>>> >>> >>> >>> >> >> >> >> -- >> ?? >> ?? >> > > > -- ?? ?? From reinier at zwitserloot.com Sun Aug 16 09:47:07 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 16 Aug 2009 18:47:07 +0200 Subject: Annotations for language features (was: Re: A Late Entry) In-Reply-To: <042d01ca1e36$97733ea0$c659bbe0$@com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <042d01ca1e36$97733ea0$c659bbe0$@com> Message-ID: <5AA96E9B-319D-493E-9BF8-4BACA46AE1E3@zwitserloot.com> Ted, I'm with you on all of that, but if I understand the purpose of coin correctly, stopping the 'tiptoeing around the java language code will break issue' is not one of its goals. I'm mostly against context sensitive keywords, because they have a negative effect on the parser's ability to give you useful error messages. I also think 'assert' is the worst case scenario; that's a keyword that was in extremely widespread use as an identifier. I'm fairly sure not one code base I've ever touched, let alone written, used 'property' as an identifier. I'm sure there are many thousands of property-as-an- identifier out there, but its small fry compared to inconveniencing everyone, for life, with a context sensitive keyword. --Reinier Zwitserloot On 2009/16/08, at 07:58, Ted Neward wrote: > I think I missed a few steps here. > >> okay, but, lets say I have some old code that uses property as an >> identifier for a class. Yes, it breaks the camelcase rule, but its >> valid java. I'm going to be a little more evil, and I'm going to name >> this field 'String', again breaking the camelcase rule, but its still >> legal. That would look like: >> >> private final property String; >> >> Can we make the parser sort this out? >> > How about even if we can't, we just say that because you named a > field after a class name (and a popular one at that), you're an > idiot and your code breaks until you fix being an idiot? In this > case, it consists of a single refactoring. Problem solved, for that > idiot, anyway. > > Seriously, I think we've been tiptoeing around the "Java language > code will break" issue for far too long. The .class files are > compatible (and even where they're not, they're tagged with a > version number so at least we can know what version they target, > *and* the JDK is reasonably easy to obtain and upgrade), so let's > just bring Java into the 21st century and make them fully-fledged > members of the keyword society. > > Yes, I remember how the community howled when Java 1.4 "broke" > JUnit. But the community howls no matter what you do, so screw 'em. > Do what's right, not what's popular. Instead of playing games that > create more edge cases than useful features, let's just rev the > language, call it "Java 2.0", and go from there. The .class file > format doesn't have to change for most of these, so I fail to see > what the major issues are here. > > My $.02 worth, anyway. > > Ted Neward > Java, .NET, XML Services > Consulting, Teaching, Speaking, Writing > http://www.tedneward.com > >> -----Original Message----- >> From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- >> bounces at openjdk.java.net] On Behalf Of Reinier Zwitserloot >> Sent: Saturday, August 15, 2009 7:51 PM >> To: coin-dev at openjdk.java.net >> Subject: Annotations for language features (was: Re: A Late Entry) >> >> http://projectlombok.org/ is a prototype that lets you play around >> with what happens when you use annotations for language features. >> >> So far, the sky has not fallen down. On the contrary; they are >> namespaced and serve as document pointers, so they've been quite >> nice. >> >> >> Sure, it may not 'feel' right, but the sheer amount of backwards >> compatibility angst suggests to me that it's a shortcut worth >> thinking >> about - even when you are careful with the keyword string you pick >> and >> the keyword is made context sensitive, the impact is larger than an >> annotation. I'd certainly not presume that all, or even most, of the >> features discussed on coindev ought to be implemented with an >> annotation, but for a select few (including properties!) it makes >> sense to me. >> >> Consider for example making 'property' a context sensitive keyword. >> >> private final property String x; >> >> okay, but, lets say I have some old code that uses property as an >> identifier for a class. Yes, it breaks the camelcase rule, but its >> valid java. I'm going to be a little more evil, and I'm going to name >> this field 'String', again breaking the camelcase rule, but its still >> legal. That would look like: >> >> private final property String; >> >> Can we make the parser sort this out? >> >> >> >> >> --Reinier Zwitserloot >> Like it? Tip it! >> http://tipit.to >> >> >> >> On 2009/16/08, at 02:38, ?? wrote: >> >>> Hi, >>> >>> 2009/8/16 Ted Neward : >>>> Oh, but come on, Neal, everybody's doing it.... *cough* JSR 308 >>>> *cough* >>>> >>>> I'll be 100% honest: I'm really worried that 308 is going to open >>>> up a whole >>>> can of worms and people are going to do exactly that: create their >>>> own >>>> customized flavors of Java by using annotations to replace >>>> keywords. But >>>> that's for a different mailing list, I suppose. >>> >>> Agreed, but I not think it worth worried. Everyone have own flavors, >>> IMO tools author should not force others flavor. Of cause the code >>> with all flavors should work with each other, that just ok. >>> >>> back to the topic. >>> 1,Property annotation maybe no the best alternative. I agreed with >>> context-sensitive, through I'm fair even ten years after it still be >> a >>> future. >>> 2,The property proposal from based on field, I called it >>> B(ottom)2T(op) style. I talk a T2B style with Adam: property can be >>> focused on method and/or field, the field not must. some kind same >>> as >>> JavaBean properties. most important, which is interface style. >>> >>>> Ted Neward >>>> Java, .NET, XML Services >>>> Consulting, Teaching, Speaking, Writing >>>> http://www.tedneward.com >>>> >>>>> -----Original Message----- >>>>> From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- >>>>> bounces at openjdk.java.net] On Behalf Of Neal Gafter >>>>> Sent: Sunday, August 09, 2009 11:22 AM >>>>> To: Greg Zoller >>>>> Cc: coin-dev at openjdk.java.net >>>>> Subject: Re: A Late Entry >>>>> >>>>> Annotations are not an appropriate "back door" for adding syntax >>>>> to the >>>>> Java >>>>> programming language. I suggest you instead consider context- >>>>> sensitive >>>>> keywords. >>>>> >>>>> On Sun, Aug 9, 2009 at 9:24 AM, Greg Zoller >>>>> wrote: >>>>> >>>>>> >>>>>> Members of coin-dev... I'm writing to submit a late proposal for >>>>>> the >>>>> Java >>>>>> language, if not for initial Java 7 release (probably too late) >> but >>>>> perhaps >>>>>> for a later release. Below is the proposal form. Plain text >>>>>> editor >>>>>> formatting is pretty inconsistent, so apologies if it looks >>>>>> poorly >>>>> formatted >>>>>> when you see it. >>>>>> >>>>>> >>>>>> Project Coin >>>>>> >>>>>> Late Submission: Hiding Accessors at Compile Time >>>>>> >>>>>> AUTHOR: Greg Zoller >>>>>> gzoller(atsign)hotmail.com >>>>>> >>>>>> OVERVIEW: >>>>>> >>>>>> Feature Summary: >>>>>> De-clutter classes littered with accessors by having the >>>>>> compiler auto-generate trivial accessors for data members >>>>>> denoted with a @property annotation. >>>>>> >>>>>> Major Advantage: >>>>>> Would eliminate lots (and lots) of messy get/set code >>>>>> without losing the benefits of having an accessor for the >>>>>> times you really need them. The proposed approach should >>>>>> not break any existing code not written to take advantage >>>>>> of the new capability. >>>>>> >>>>>> Major Benefit: >>>>>> Less cluttered code! Removes (or more specifically hides >>>>>> behind the compiler) the clumsy construct of accessors >>>>>> without losing the purpose and benfits of their existence. >>>>>> In other words, I want property accessor capability--I >>>>>> just don't want to see them! >>>>>> >>>>>> Major Disadvantage: >>>>>> None that come to mind--I'm sure someone will contribute a >>>>>> disadvantage. >>>>>> >>>>>> Alternatives: >>>>>> Leave things the way they are. >>>>>> >>>>>> EXAMPLES: >>>>>> >>>>>> /* Today */ >>>>>> public class Foo { >>>>>> private String name; // no accessors for name >>>>>> private int age; >>>>>> private double balance; >>>>>> private String comment; >>>>>> >>>>>> public int getAge() { return this.age; } >>>>>> public void setAge(int age) { this.age = age; } >>>>>> public double getBalance() { return this.balance; } >>>>>> public void setComment(String comment) { >>>>>> this.comment = comment; } >>>>>> } >>>>>> >>>>>> /* Proposed */ >>>>>> public class Foo { >>>>>> private String name; // no accessors generated >>>>>> @property private int age; // both get/set generated >>>>>> @property(GET) private double balance; // getter >> generated, >>>>> no >>>>>> setter >>>>>> @property(SET) private String comment; // setter >> generated, >>>>> no >>>>>> getter >>>>>> } >>>>>> >>>>>> // Code would use these properties via their generated >>>>>> // accessors as they do now: >>>>>> foo.setAge(foo.getAge() + 10); >>>>>> >>>>>> // EVEN BETTER... the compiler can try to resolve data member >>>>>> // access according to a scope/visibility hierarchy: >>>>>> // public member, protected member, private member, >>>>>> // inserted getter/setter call >>>>>> >>>>>> // If this can be done in the compiler then old code can still >>>>>> // call the accessors like always while new code could simply >>>>>> // have: >>>>>> >>>>>> foo.age += 10; >>>>>> System.out.println("Age: "+foo.age); >>>>>> >>>>>> // This looks as clean as direct data member access but age >>>>>> // remains private with all the benefits of having accessor >>>>>> // protection. In the example above assuming no public, >>>>>> // protected, or private visibility for age exists the compiler >>>>>> // will insert a call to foo.getAge() for the programmer if age >>>>>> // is a @property field (otherwise its a compile error). >>>>>> >>>>>> // NOTE: The compiler won't auto-generate a getter or setter >> if >>>>>> // one already has been specified by the programmer, allowing >>>>>> // full control like we have now: >>>>>> >>>>>> public class Foo { >>>>>> @property private int age; // only a trivial getter >>>>>> generated--setter exists >>>>>> public void setAge(int age) { >>>>>> msg.notify("Someone's tampering with age!"); >>>>>> this.age = age; >>>>>> } >>>>>> } >>>>>> >>>>>> // The compiler would exercise precedence logic in deciding >>>>>> // whether to insert a call to the accessors or not >>>>>> >>>>>> package A; >>>>>> public class Foo { >>>>>> @property private int age; // only setter generated-- >> getter >>>>> exists >>>>>> public int getAge() { >>>>>> System.out.println("Getter called!"); >>>>>> return this.age; >>>>>> } >>>>>> public void something() { >>>>>> int anotherAge = this.age; >>>>>> // private visibility is valid--no compiler-inserted >>>>>> // call to this.getAge() here >>>>>> >>>>>> int oneMoreAge = this.getAge(); >>>>>> // explicit call to getter ok--just like today >>>>>> } >>>>>> } >>>>>> >>>>>> package B; >>>>>> public class Bar { >>>>>> public void blah(Foo foo) { >>>>>> System.out.println(foo.age); >>>>>> // Compiler can't resolve public, protected, or >>>>>> // private visibility to foo.age so a call to the >>>>>> // generated foo.getAge() accessor is inserted >>>>>> } >>>>>> } >>>>>> >>>>>> DETAILS >>>>>> >>>>>> Specification: >>>>>> Add the FIELD-targeted @property annotation to the >>>>>> language. Without parameters this will cause the >>>>>> generation of both a getter and setter unless one is >>>>>> already given by the programmer. >>>>>> >>>>>> Optional parameters GET or SET (@property(GET) or >>>>>> @property(SET)) would only attempt to generate the getter >>>>>> or setter respectively. I don't think Java grammar would >>>>>> be affected (?). >>>>>> >>>>>> Compilation: >>>>>> Out of my depth here. The auto-generation feature *should* >>>>>> be very straightforward as I would hope all the needed info >>>>>> to create the getters/setters is available at compile-time. >>>>>> I'm less clear on whether the compiler would be able to do >>>>>> the auto-resolution so you could just use foo.age and >>>>>> wouldn't be forced to call foo.getAge()/foo.setAge(), but >>>>>> I'm hopeful this is also possible, as it would be a great >>>>>> feature. >>>>>> >>>>>> This logic would have to support a hierarchy of resolution >>>>>> so that if 'age' was a public data member then public >>>>>> access would take precedence over trying to call the >>>>>> accessor method. Likewise protected and private access >>>>>> would take precedence over the getter if normal >>>>>> visibility rules allowed this mode of access. >>>>>> >>>>>> Testing: >>>>>> Hmm... >>>>>> >>>>>> Library Support: >>>>>> Shouldn't require any library support >>>>>> >>>>>> Reflective APIs: >>>>>> Existing APIs should be fine. The generated >>>>>> getters/setters would be reflectively accessible since once >>>>>> they are generated by the compiler they are no different >>>>>> than if the programmer had written them. >>>>>> >>>>>> Other Changes: >>>>>> None come to mine. >>>>>> >>>>>> Migration: >>>>>> No conversion necessary. Normal getter/setter code in >>>>>> common use today would still work and could live seamlessly >>>>>> in parallel with code using the new features. >>>>>> >>>>>> COMPATIBILITY: >>>>>> >>>>>> Breaking Changes: >>>>>> No code should break due to the changes proposed >>>>>> >>>>>> Existing Programs: >>>>>> Existing code should live seamlessly in parallel to these >>>>>> changes. If the compiler access precidence feature is >>>>>> implemented then newly written code can take advantage of >>>>>> this ability when calling existing unmodified code. For >>>>>> example: >>>>>> >>>>>> // Existing code >>>>>> public class Foo { >>>>>> private int age; >>>>>> public int getAge() { return this.age; } >>>>>> public void setAge(int age) { this.age = age; } >>>>>> } >>>>>> >>>>>> // New code >>>>>> foo.age = 10; >>>>>> >>>>>> // compiler would first see if a public/protected/private >>>>>> // visible age data member existed, and since there is none >>>>>> // a call to getAge() would be inserted during compile time >>>>>> // thus using the new feature to seamlessly interact with >>>>>> // legacy code without altering semantics >>>>>> >>>>>> REFERENCES: >>>>>> N/A >>>>>> >>>>>> >>>>>> _________________________________________________________________ >>>>>> Get free photo software from Windows Live >>>>>> >>>>>> >>>>> >> http://www.windowslive.com/online/photos?ocid=PID23393::T:WLMTAGL:ON:WL >>>>> :en-US:SI_PH_software:082009 >>>>>> >>>>>> >>>> >>>> >>>> >>> >>> >>> >>> -- >>> ?? >>> ?? >>> >> > > From reinier at zwitserloot.com Sun Aug 16 09:53:49 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 16 Aug 2009 18:53:49 +0200 Subject: Annotations for language features In-Reply-To: <4A87BD44.4060406@adres.pl> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> Message-ID: <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> Not quite, Arthur: Annotation processors can create *NEW* source files. (Let's call those generated source files). Real source files can refer to types that exist in generated source files. In fact, the real source file that contains the annotation that created the generated source file can refer to the generated source file. Attempting to compile this code while you turn your annotation processors off will mean the code doesn't compiler. Sure, no annotations in the core java libraries actually create generated source files, but the ability to generate files clearly isn't an afterthought; it's a very valuable part of the annotation system. I don't see why you are perfectly willing to accept crippling valid uses of the annotation system like that. Can you explain to me why you adhere to this rule of thumb? What are the advantages? What are the disadvantages? Reasons are nice. > Next step and we will end up Borland > Pascal way and put control instructions in comments/javadoc. That's a logical fallacy. Please try to keep your emotions out of this discussion. Read up here: http://www.nizkor.org/features/fallacies/slippery-slope.html --Reinier Zwitserloot On 2009/16/08, at 10:03, Artur Biesiadowski wrote: > Reinier Zwitserloot wrote: >> http://projectlombok.org/ is a prototype that lets you play around >> with what happens when you use annotations for language features. >> >> So far, the sky has not fallen down. On the contrary; they are >> namespaced and serve as document pointers, so they've been quite >> nice. >> > > For me, rule of thumb is: if you remove all properties from the source > code (everywhere, libraries and user code), code should still compile. > It can fail only on runtime and only because somebody is explicitly > using reflection to retrieve annotations. So far, all official > annotations and all proposed ones follow this rule. Even JSR 308 is > the > same - type annotations are optional, meaning that if you would remove > them from std lib and your code, everything would compile properly. > > Project lombok is interesting hack, but I would never, ever like to > see > it happening to official java. Next step and we will end up Borland > Pascal way and put control instructions in comments/javadoc. > > With best regards, > Artur Biesiadowski > From abies at adres.pl Sun Aug 16 11:23:18 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Sun, 16 Aug 2009 20:23:18 +0200 Subject: Annotations for language features In-Reply-To: <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> Message-ID: <4A884E96.2060108@adres.pl> Reinier Zwitserloot wrote: > > Sure, no annotations in the core java libraries actually create > generated source files, but the ability to generate files clearly > isn't an afterthought; it's a very valuable part of the annotation system. There is a difference between generating additional code from annotations (like many remote invocation wrappers do) and actually changing what the code containing the annotations does. I think it is a matter of taste. For me the line is somewhere between having annotation @NonNegative int x; which gives annotation-aware compiler right to reject/warn on certain assignments, versus @Unsigned int x; which would mean that this int is treated as real unsigned integer on all comparisons/shifts/etc (maybe even using different set of bytecodes in future jvm). Same way, for me @Property int x; would be acceptable as a kind of marker for compiler which would reject source file if it doesn't contain properly constructed getters and setters, but not as something which silently generates missing methods. You asked for the reasons and I must say that I'm in trouble to find any hard ones. I think that for me main thing is to avoid 'hackery' in language because of compatibility reasons only. There is considerable hackery in implementation already (private field/method accesors from inner classes, generics erasure) - but whatever you can say about generics, they got implemented as Map x; instead of @Map(String.class,Something.class) Map x; I feel that language extensions should be kept this way - even if it is costly in term on compiler support. > > Next step and we will end up Borland > > Pascal way and put control instructions in comments/javadoc. > > That's a logical fallacy. It might look like one, but I have already been through that when discussing Design By Contract support in java long time ago. Take a look at http://www.mmsindia.com/DBCForJava.html for example for a solution which takes this route. Today, with annotations, we probably won't actually end up back in javadoc code generation camp, but this was more a mindset rather than particular solution I was referring to. With best regards, Artur Biesiadowski From amalter at illegalcheese.com Sun Aug 16 11:45:45 2009 From: amalter at illegalcheese.com (Adam Malter) Date: Sun, 16 Aug 2009 14:45:45 -0400 Subject: Annotations for language features In-Reply-To: <4A884E96.2060108@adres.pl> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> Message-ID: <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> On Sun, Aug 16, 2009 at 2:23 PM, Artur Biesiadowski wrote: > Reinier Zwitserloot wrote: >> >> Sure, no annotations in the core java libraries actually create >> generated source files, but the ability to generate files clearly >> isn't an afterthought; it's a very valuable part of the annotation system. > There is a difference between generating additional code from > annotations (like many remote invocation wrappers do) and actually > changing what the code containing the annotations does. > > I think it is a matter of taste. For me the line is somewhere between > having annotation > > @NonNegative int x; > > which gives annotation-aware compiler right to reject/warn on certain > assignments, versus > > @Unsigned int x; > > which would mean that this int is treated as real unsigned integer on > all comparisons/shifts/etc (maybe even using different set of bytecodes > in future jvm). Same way, for me > > @Property int x; > > would be acceptable as a kind of marker for compiler which would reject > source file if it doesn't contain properly constructed getters and > setters, but not as something which silently generates missing methods. > > You asked for the reasons and I must say that I'm in trouble to find any > hard ones. I think that for me main thing is to avoid 'hackery' in > language because of compatibility reasons only. There is considerable > hackery in implementation already (private field/method accesors from > inner classes, generics erasure) - but whatever you can say about > generics, they got implemented as Map x; instead of > @Map(String.class,Something.class) Map x; I feel that language > extensions should be kept this way - even if it is costly in term on > compiler support. > >> > Next step and we will end up Borland >> > Pascal way and put control instructions in comments/javadoc. >> >> That's a logical fallacy. > It might look like one, but I have already been through that when > discussing Design By Contract support in java long time ago. Take a look at > http://www.mmsindia.com/DBCForJava.html > for example for a solution which takes this route. Today, with > annotations, we probably won't actually end up back in javadoc code > generation camp, but this was more a mindset rather than particular > solution I was referring to. > > With best regards, > Artur Biesiadowski > > I think anybody who's worked with 'code generating' annotation processors could enumerate a number of good reasons to stay away. They have been universally fragile, difficult to test, difficult to code and difficult to debug. Additionally, they place a serious complexity and runtime strain on development tools. The 'code' must be generated realtime in order to preserve 'as your type' error hints (aka, insure an accurate AST model with references back to true source code). Additionally, they introduce dependency graphs that are not clearly resolved even by the current generation of annotation parsers (See Joe Darcy's attempt to build a *third* Apt API in as many versions of Java and then lookup the concept of generation rounds in the Eclipse apt development documentation) All those nice Eclipse/Idea/Netbeans features like dynamic method lookup, error highlighting, templating, etc, must run the annotation processors/plugins on the entire codebase as you go. This works fine for smaller codebases, but as projects get larger, the pressure to keep the dynamically generated code in sync with refactors and back merges and et. al, gets harder and harder. Also, the hurdle for building a Java IDE with these basic features is raised. I believe that tools like Project Lombok are useful for illustrating new paths the language can take, but I'd be hesitant to integrate any library using it into any production project. While the class files for the library may be 'JVM' compatible, without the exact version of the plugin, the source files might as well be Groovy or Scala (aka, opaque to the java developer) - I know this hyperbole, we are only talking about getters/setters, but the slippery slope argument is no fallacy if you've ever used DTO annotation processors for the major enterprise stacks. Generated code is a useful trick up the language's sleeve to help make very complex tasks automated, but it's use in the base classpath should be discouraged if not forbidden. As an alternative, if what the @Property annotation did was both create the getters/setters in the original source, validated them if they were already present, and served as a hint to aware IDE's (which would then hide the boiler plate), I'd be on board 100%. The line between hinting and validation vs opaque creation is wide and the downsides make it not worth crossing. IMHO of course :) -adam malter @ tradecard From Joe.Darcy at Sun.COM Sun Aug 16 12:17:49 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 16 Aug 2009 12:17:49 -0700 Subject: Annotations for language features In-Reply-To: <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> Message-ID: <4A885B5D.8070905@sun.com> Adam Malter wrote: > On Sun, Aug 16, 2009 at 2:23 PM, Artur Biesiadowski wrote: > >> Reinier Zwitserloot wrote: >> >> [snip] > > I think anybody who's worked with 'code generating' annotation > processors could enumerate a number of good reasons to stay away. > > They have been universally fragile, difficult to test, difficult to > code and difficult to debug. Additionally, they place a serious > complexity and runtime strain on development tools. The 'code' must be > generated realtime in order to preserve 'as your type' error hints > (aka, insure an accurate AST model with references back to true source > code). Additionally, they introduce dependency graphs that are not > clearly resolved even by the current generation of annotation parsers > (See Joe Darcy's attempt to build a *third* Apt API in as many > versions of Java and then lookup the concept of generation rounds in > the Eclipse apt development documentation) > I don't know what attempt at a third API you are referring to. The apt tool and API was always planned to be "the one we throw away" in the "The Mythical Man-Month" sense, which is why it has been deprecated in JDK 7 and is planned for removal in a future JDK release. The JSR 269 API (javax.annotation.processing, javax.lang.model.*) improves significantly on apt and JSR 269 was informed by experiences BEA engineers gained from implementing apt in an IDE. The JSR 269 API is being tweaked a bit in JDK 7 and can be expected to change further to support new language features. Supporting language evolution smoothly was a key technical goal of JSR 269 specifically to *avoid* introducing yet another API in JDK 7. -Joe From reinier at zwitserloot.com Sun Aug 16 12:27:23 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 16 Aug 2009 21:27:23 +0200 Subject: Annotations for language features In-Reply-To: <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> Message-ID: On 2009/16/08, at 20:45, Adam Malter wrote: > They have been universally fragile, difficult to test, difficult to > code and difficult to debug. Huh? We're talking about using annotations as language features. Tool support isn't relevant to this discussion at all - whether assert was done as 'assert (boolean);' or as "@Assert (expression);" (supposing that would be legal) is irrelevant to how well or badly eclipse and other tools would support it. > The 'code' must be > generated realtime in order to preserve 'as your type' error hints Exactly, which is why lombok does what it does. the AST reflects what you typed, immediately. > All those nice Eclipse/Idea/Netbeans features like dynamic method > lookup, error highlighting, templating, etc, must run the annotation > processors/plugins on the entire codebase as you go. So? Lombok's performance impact on either javac or eclipse is not measurable. And yet the lombok transformation core is run by eclipse everytime you type a character. > > Also, the hurdle for building a Java IDE with these basic features > is raised. > No, it's lowered. We're now speaking about two entirely different things, but either way, Java IDE authors will be happy with you. If we're talking about hardcoding the meaning and result of annotations into the JLS (Such as @Override), then Java IDEs have it marginally easier compared to introducing a keyword, because they don't need to make changes to their grammar processor. A *LOT* of coin proposals involved syntactic formats which either didn't even fit the LL(1) model, or would have been non-trivial to implement for grammar parsers. If you for example look at the difference between the eclipse parser pre- and post- java1.5 additions, you'd barely recognize the parser codebase. Annotations can only be useful for a fraction of those issues (quick: Name a java 1.5 language feature that could have been done with annotations instead. I can't think of even one!) - but where annotations fit, the AST building process does not have to change at all - much easier for IDE developers. If we're talking about a 'roll your own language features' framework, e.g. making AST rewriting a plugin architecture like lombok, then IDE developers will be *much* happier with you. They add support for this admittedly complex thing once, and then most further features are delivered either directly in the JDK via sunoracle, or they themselves write for this framework. Their IDEs would be compatible with feature java language features right off the bat. > I believe that tools like Project Lombok are useful for illustrating > new paths the language can take, but I'd be hesitant to integrate any > library using it into any production project. You can't tell. No, really - you cannot tell if a library uses lombok unless you inspect the source code. Lombok produces class files that are indistinguishable from the class files generated if you hadn't used lombok and instead wrote it out longhand. > > While the class files for the library may be 'JVM' compatible, without > the exact version of the plugin, the source files might as well be > Groovy or Scala (aka, opaque to the java developer) That's just not true. If you see: private @Getter int x; you're not really going to argue here that you, or any other java programmer is going to be as utterly baffled by what's happening, as if you rewrote the whole thing in scala, right? Or, to be a bit more fair about it, isn't this true for *ANY* new language feature? Therefore your argument boils down to: Java should never change, ever, ever, ever, because people will get confused, and it'll be like a new language. We could argue that, at length, but then why are you even on coindev in the first place? As an argument it has some merit against adding a 'roll-your-own' framework to java itself, but I don't think that's what we're talking about, and such a framework would most definitely be off limits for coin anyway. lombok-produced class files do not have a dependency on lombok.jar and are indistinguishable from class files generated by javac (or eclipse) sans lombok but written out. > - I know this > hyperbole, we are only talking about getters/setters, but the slippery > slope argument is no fallacy Slippery Slope is by definition a fallacy. You just cannot argue 'This is going to devolve into insanity' without showing a likely course of events for how that would happen. So far you've given me absolutely no indication. I'll get things started with a counter-proof: Between the various tricks as shown in the Java Puzzlers book, and abusing reflection, it seems clear that anybody could easily write utterly fragile, impossible to read or maintain code. And yet the java community writes code that is by and large readable. Therefore, your 'giving the programmers tools that could possibly be used to shoot oneself in the foot is going to lead to severe problems' is just a falsehood. I'll prove it to you, even: In order for a language to be turning complete, something we generally want in our programming languages, you also give the programmer the ability to shoot themselves in the foot. That's the price you pay for allowing code to be sufficiently expressive to do anything. So far nobody's managed to build a language that is turing complete and yet prevents you from writing shoddy code. So, -yet again-, I implore all to move away from these hyperbolic gestures of 'that way lies the madness', and actually show HOW the madness could happen, and discuss BOTH sides of the coin here: It'll make java code harder to follow mechanically (what -exactly- does this do), but it'll make code easier to read (you can express the same thing on a higher level, which is easier for a human brain to get the gist of). Generics has undoubtedly made understanding how java code actually works -MUCH- harder, but on the flipside, a lot of code has become much more readable, because you now know exactly what's in all those lists and maps. The discussion on whether the cost was worth the gain is of course a complex one, but it's nevertheless the one we should be having. Personally, I'm of the conviction that generating getters and setters by annotating (with an annotation or a keyword) the field causes barely any confusion, and makes code -muuuch- easier to maintain and read. It's got a great value for a marginal cost. We should add things that offer good value for low costs. > As an alternative, if what the @Property annotation did was both > create the getters/setters in the original source, validated them if > they were already present, and served as a hint to aware IDE's (which > would then hide the boiler plate), I'd be on board 100%. > That's what lombok does (well, not with @Property, but with @Getter and @Setter). Unless you mean actually write the physical characters into the source file, but that's a rather preposterous maintainance nightmare - you'd be burdened with rather a lot of content to read just to go: "Oh, this entire 3-page thing was just generated by 7 lines of code and 5 annotations!" - that's rather a spectacular waste of everyone's time. You'd also be incapable of editing things - unless you propose that the @Property annotation magically knows the name of its field before you edited that name, and removes those setters and getters while adding the new one. A final note on the current state of the APT API: It's a great API. I recall Joe saying that the original sun.* API was always intended to be a testrun, so that the true API (javax.annotation.*) can be better. It paid off well - the javax.annotation.* API is easy to write against, and the code you end up with is quite readable. I know of many APIs that are part of the core java platform where this does not at all hold. Example: Getting type info via reflection including the generics. That API (.getGenericReturnType() and friends) is horrid. I wish they did the "testrun once - build it properly after that" approach for that one. From amalter at illegalcheese.com Sun Aug 16 13:11:26 2009 From: amalter at illegalcheese.com (Adam Malter) Date: Sun, 16 Aug 2009 16:11:26 -0400 Subject: Annotations for language features In-Reply-To: <4A885B5D.8070905@sun.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> <4A885B5D.8070905@sun.com> Message-ID: <613a548a0908161311n1ee08ee9sb3388d7bcd99a710@mail.gmail.com> Joe - I apologize then, I read the tweaking of JSR 269 to be further towards a new api than an evolution of the current. I did not mean to spread mis-information. I will admit I am a bit gun shy about this issue, having to support a com.sun.apt Processor, JSR 269 processor and Eclipse PlugIn (using the eclipse ast) to enable some of the neat 'features' we want for our implementation developers. Everything seems to work a bit differently depending on where and how you compile. It's this lesson though that I wish to convey when I express fear about core features enabled by code parsing and generating in the JDK. Reinier - Currently I'm working on an 11m LOC financial services project. (Yes, I know, it needs to be broken up) - I'm doing a branch right now to play with Lombok, but considering that Eclipse currently has trouble processing the source tree whenever I do heirarchy view or outline view, and I know what code is run by Eclipse plugins 'on every keystroke', I have my worries. The 'Huh?' shrug when we're discussing language features vs tooling support is disingenuous at best. I know you wrote a language tool to demonstrate features. So, you must understand that the language features *must* be supportable by the toolchains. One of the great features about Java is it's ability to be safely refactored (Tool based). This comes from the strong type system built into the language (Language Based). The language, and the tools it enables are strongly intertwined. Ruby will never be able to have a (safe) refactor system because of this interdependency. I understand that one "can't" tell from the classfiles if the author used Project Lombok or not. But, I'm only vaguely interested in the class files, what I'm really interested in is the source code. The primary reason we stay away from closed source projects is not because of the cost (well, sometimes it is, but mostly not), but because without access to the source code from my well tooled IDE, I often cannot make reasoned implementation decisions. Whether or not I under private @Property country or not, what if when I do a search by reference on a piece of de-coupled code that says 'purchaseOrder.getCountry()' If my IDE is not 'Lombok' blessed, I might be able to find the referencing class, but certainly not the line of code executing. When I debug it, I'll drop into either a synthetic method, or maybe the .aptGenerated source. I'm not arguing over using annotations vs keywords. I understand that they both have pro's and con's when adding functionality. In this case it's the functionality I'm specifically against. Using either of them to 'generate' boilerplate code. This magic code becomes invisible and just adds to the complexity budget of the language. Don't believe me, come over to the dark side where I had to painfully explain to an implementation developer that he didn't need to create a static List of his enum values on construction. He did not understand that every enum came off the Enum class, and even then, the values() method is not even mentioned in the source. (Which I know, it's pretty easy thing, but could we have not made like an abstract method or something there, then you'd get a Javadoc, etc) And I'm consistent about this, I hate that arrays have the magic length property. At least your proposal includes instructions in the source. Hey, if it's just about @Property, well I suppose your right, because it's so simple, because everyone can understand it, I'd give ground on that. But, it's not. Lets slide down the imaginery slippery slope and end up with @EqualsAndHashCode - Well, sure, get/set are easy, boilerplate, never implented differently. But .equals() and .hashCode()? Simple if all you have are a bunch of primitives, but start throwing those around in a moderately complex project, and if you've got a mess real quick. At least with Eclipse's autogenerate, I can see what's going on, tweak it if I know that including a reference to a giant string property would kill my hashcode when I've got a perfectly good primary key generated by ORM. And @Data, well, I will argue that many reasonable programmers will be baffled by what that does. And what happens if I take your source and compile with a different version of Project Lombok (maybe you found a bug in .equals() template, not impossible, apache commons certainly showed that). Maybe I am too used to being able to checkout projects by source and compile them. And then have a reasonable expectation that they will work the same as the delivered binary. Sure, as things stand right now all sorts of stuff can go wrong. I can have the wrong jdk version, or dependencies or whatever, but the point is that adding auto-generation magic, no matter how, makes the situation worse, not better. -adam malter On Sun, Aug 16, 2009 at 3:17 PM, Joseph D. Darcy wrote: > Adam Malter wrote: >> >> On Sun, Aug 16, 2009 at 2:23 PM, Artur Biesiadowski wrote: >> >>> >>> Reinier Zwitserloot wrote: >>> > > [snip] >> >> I think anybody who's worked with 'code generating' annotation >> processors could enumerate a number of good reasons to stay away. >> >> They have been universally fragile, difficult to test, difficult to >> code and difficult to debug. Additionally, they place a serious >> complexity and runtime strain on development tools. The 'code' must be >> generated realtime in order to preserve 'as your type' error hints >> (aka, insure an accurate AST model with references back to true source >> code). ?Additionally, they introduce dependency graphs that are not >> clearly resolved even by the current generation of annotation parsers >> (See Joe Darcy's attempt to build a *third* Apt API in as many >> versions of Java and then lookup the concept of generation rounds in >> the Eclipse apt development documentation) >> > > I don't know what attempt at a third API you are referring to. > > The apt tool and API was always planned to be "the one we throw away" in the > "The Mythical Man-Month" sense, which is why it has been deprecated in JDK 7 > and is planned for removal in a future JDK release. > > The JSR 269 API (javax.annotation.processing, javax.lang.model.*) improves > significantly on apt and JSR 269 was informed by experiences BEA engineers > gained from implementing apt in an IDE. > > The JSR 269 API is being tweaked a bit in JDK 7 and can be expected to > change further to support new language features. ?Supporting language > evolution smoothly was a key technical goal of JSR 269 specifically to > *avoid* introducing yet another API in JDK 7. > > -Joe > > From reinier at zwitserloot.com Sun Aug 16 16:55:03 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 17 Aug 2009 01:55:03 +0200 Subject: Annotations for language features In-Reply-To: <613a548a0908161311n1ee08ee9sb3388d7bcd99a710@mail.gmail.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> <4A885B5D.8070905@sun.com> <613a548a0908161311n1ee08ee9sb3388d7bcd99a710@mail.gmail.com> Message-ID: Now you're attacking lombok itself. That's all fine, but how this is relevant to project coin? I've taken the rest of this discussion to email. If anyone else is interested, please email me and I'll post our emails (with the fiat of Adam, of course!) to the project lombok newsgroup. On 2009/16/08, at 22:11, Adam Malter wrote: > Joe - I apologize then, I read the tweaking of JSR 269 to be further > towards a new api than an evolution of the current. I did not mean to > spread mis-information. > > I will admit I am a bit gun shy about this issue, having to support a > com.sun.apt Processor, JSR 269 processor and Eclipse PlugIn (using the > eclipse ast) to enable some of the neat 'features' we want for our > implementation developers. > > Everything seems to work a bit differently depending on where and how > you compile. It's this lesson though that I wish to convey when I > express fear about core features enabled by code parsing and > generating in the JDK. > > Reinier - Currently I'm working on an 11m LOC financial services > project. (Yes, I know, it needs to be broken up) - I'm doing a branch > right now to play with Lombok, but considering that Eclipse currently > has trouble processing the source tree whenever I do heirarchy view or > outline view, and I know what code is run by Eclipse plugins 'on every > keystroke', I have my worries. > > The 'Huh?' shrug when we're discussing language features vs tooling > support is disingenuous at best. I know you wrote a language tool to > demonstrate features. So, you must understand that the language > features *must* be supportable by the toolchains. One of the great > features about Java is it's ability to be safely refactored (Tool > based). This comes from the strong type system built into the language > (Language Based). The language, and the tools it enables are strongly > intertwined. Ruby will never be able to have a (safe) refactor system > because of this interdependency. > > I understand that one "can't" tell from the classfiles if the author > used Project Lombok or not. But, I'm only vaguely interested in the > class files, what I'm really interested in is the source code. The > primary reason we stay away from closed source projects is not because > of the cost (well, sometimes it is, but mostly not), but because > without access to the source code from my well tooled IDE, I often > cannot make reasoned implementation decisions. > > Whether or not I under private @Property country or not, what if when > I do a search by reference on a piece of de-coupled code that says > 'purchaseOrder.getCountry()' > > If my IDE is not 'Lombok' blessed, I might be able to find the > referencing class, but certainly not the line of code executing. When > I debug it, I'll drop into either a synthetic method, or maybe the > .aptGenerated source. > > I'm not arguing over using annotations vs keywords. I understand that > they both have pro's and con's when adding functionality. In this case > it's the functionality I'm specifically against. Using either of them > to 'generate' boilerplate code. This magic code becomes invisible and > just adds to the complexity budget of the language. > > Don't believe me, come over to the dark side where I had to painfully > explain to an implementation developer that he didn't need to create a > static List of his enum values on construction. He did not understand > that every enum came off the Enum class, and even then, the values() > method is not even mentioned in the source. (Which I know, it's pretty > easy thing, but could we have not made like an abstract method or > something there, then you'd get a Javadoc, etc) > > And I'm consistent about this, I hate that arrays have the magic > length property. At least your proposal includes instructions in the > source. > > Hey, if it's just about @Property, well I suppose your right, because > it's so simple, because everyone can understand it, I'd give ground on > that. But, it's not. Lets slide down the imaginery slippery slope and > end up with @EqualsAndHashCode - Well, sure, get/set are easy, > boilerplate, never implented differently. But .equals() and > .hashCode()? Simple if all you have are a bunch of primitives, but > start throwing those around in a moderately complex project, and if > you've got a mess real quick. At least with Eclipse's autogenerate, I > can see what's going on, tweak it if I know that including a reference > to a giant string property would kill my hashcode when I've got a > perfectly good primary key generated by ORM. And @Data, well, I will > argue that many reasonable programmers will be baffled by what that > does. > > And what happens if I take your source and compile with a different > version of Project Lombok (maybe you found a bug in .equals() > template, not impossible, apache commons certainly showed that). > > Maybe I am too used to being able to checkout projects by source and > compile them. And then have a reasonable expectation that they will > work the same as the delivered binary. Sure, as things stand right now > all sorts of stuff can go wrong. I can have the wrong jdk version, or > dependencies or whatever, but the point is that adding auto-generation > magic, no matter how, makes the situation worse, not better. > > -adam malter > > On Sun, Aug 16, 2009 at 3:17 PM, Joseph D. Darcy > wrote: >> Adam Malter wrote: >>> >>> On Sun, Aug 16, 2009 at 2:23 PM, Artur >>> Biesiadowski wrote: >>> >>>> >>>> Reinier Zwitserloot wrote: >>>> >> >> [snip] >>> >>> I think anybody who's worked with 'code generating' annotation >>> processors could enumerate a number of good reasons to stay away. >>> >>> They have been universally fragile, difficult to test, difficult to >>> code and difficult to debug. Additionally, they place a serious >>> complexity and runtime strain on development tools. The 'code' >>> must be >>> generated realtime in order to preserve 'as your type' error hints >>> (aka, insure an accurate AST model with references back to true >>> source >>> code). Additionally, they introduce dependency graphs that are not >>> clearly resolved even by the current generation of annotation >>> parsers >>> (See Joe Darcy's attempt to build a *third* Apt API in as many >>> versions of Java and then lookup the concept of generation rounds in >>> the Eclipse apt development documentation) >>> >> >> I don't know what attempt at a third API you are referring to. >> >> The apt tool and API was always planned to be "the one we throw >> away" in the >> "The Mythical Man-Month" sense, which is why it has been deprecated >> in JDK 7 >> and is planned for removal in a future JDK release. >> >> The JSR 269 API (javax.annotation.processing, javax.lang.model.*) >> improves >> significantly on apt and JSR 269 was informed by experiences BEA >> engineers >> gained from implementing apt in an IDE. >> >> The JSR 269 API is being tweaked a bit in JDK 7 and can be expected >> to >> change further to support new language features. Supporting language >> evolution smoothly was a key technical goal of JSR 269 specifically >> to >> *avoid* introducing yet another API in JDK 7. >> >> -Joe >> >> From ted at tedneward.com Sun Aug 16 20:10:57 2009 From: ted at tedneward.com (Ted Neward) Date: Sun, 16 Aug 2009 20:10:57 -0700 Subject: Annotations for language features In-Reply-To: <4A885B5D.8070905@sun.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> <4A885B5D.8070905@sun.com> Message-ID: <00b001ca1ee8$60378e20$20a6aa60$@com> > The apt tool and API was always planned to be "the one we throw away" > in > the "The Mythical Man-Month" sense, which is why it has been deprecated > in JDK 7 and is planned for removal in a future JDK release. > In hindsight, that's easy to say; I don't remember any sort of statement to that effect when it was first shipped. I'm not making accusations or espousing conspiracy theories, I just simply want to raise the idea that apt was viewed by many--including me--as "the" Sun-blessed way to write annotation processors. Let me throw this in to the mix: what, for Java7, is similarly intended as "the one we (Sun) plan to throw away"? Ted Neward Java, .NET, XML Services Consulting, Teaching, Speaking, Writing http://www.tedneward.com ? > -----Original Message----- > From: coin-dev-bounces at openjdk.java.net [mailto:coin-dev- > bounces at openjdk.java.net] On Behalf Of Joseph D. Darcy > Sent: Sunday, August 16, 2009 12:18 PM > To: Adam Malter > Cc: coin-dev at openjdk.java.net > Subject: Re: Annotations for language features > > Adam Malter wrote: > > On Sun, Aug 16, 2009 at 2:23 PM, Artur Biesiadowski > wrote: > > > >> Reinier Zwitserloot wrote: > >> > >> > > [snip] > > > > I think anybody who's worked with 'code generating' annotation > > processors could enumerate a number of good reasons to stay away. > > > > They have been universally fragile, difficult to test, difficult to > > code and difficult to debug. Additionally, they place a serious > > complexity and runtime strain on development tools. The 'code' must > be > > generated realtime in order to preserve 'as your type' error hints > > (aka, insure an accurate AST model with references back to true > source > > code). Additionally, they introduce dependency graphs that are not > > clearly resolved even by the current generation of annotation parsers > > (See Joe Darcy's attempt to build a *third* Apt API in as many > > versions of Java and then lookup the concept of generation rounds in > > the Eclipse apt development documentation) > > > > I don't know what attempt at a third API you are referring to. > > The apt tool and API was always planned to be "the one we throw away" > in > the "The Mythical Man-Month" sense, which is why it has been deprecated > in JDK 7 and is planned for removal in a future JDK release. > > The JSR 269 API (javax.annotation.processing, javax.lang.model.*) > improves significantly on apt and JSR 269 was informed by experiences > BEA engineers gained from implementing apt in an IDE. > > The JSR 269 API is being tweaked a bit in JDK 7 and can be expected to > change further to support new language features. Supporting language > evolution smoothly was a key technical goal of JSR 269 specifically to > *avoid* introducing yet another API in JDK 7. > > -Joe From Joe.Darcy at Sun.COM Sun Aug 16 22:36:18 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 16 Aug 2009 22:36:18 -0700 Subject: Annotations for language features In-Reply-To: <00b001ca1ee8$60378e20$20a6aa60$@com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> <4A885B5D.8070905@sun.com> <00b001ca1ee8$60378e20$20a6aa60$@com> Message-ID: <4A88EC52.5050904@sun.com> Ted Neward wrote: >> The apt tool and API was always planned to be "the one we throw away" >> in >> the "The Mythical Man-Month" sense, which is why it has been deprecated >> in JDK 7 and is planned for removal in a future JDK release. >> >> > In hindsight, that's easy to say; I don't remember any sort of statement to > that effect when it was first shipped. I'm not making accusations or > First, the apt API is a com.sun.* API and not an official java or javax API; second, since shipping in JDK 5 the apt javadoc has stated "Note that the apt tool and its associated APIs may be changed or superseded in future j2se releases:" http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/com/sun/mirror/apt/package-summary.html http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/com/sun/mirror/declaration/package-frame.html http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/com/sun/mirror/type/package-summary.html http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/com/sun/mirror/util/package-summary.html > espousing conspiracy theories, I just simply want to raise the idea that apt > was viewed by many--including me--as "the" Sun-blessed way to write > annotation processors. > It was in JDK 5 and ceased to be the recommended way to write annotation processors once JSR 269 shipped in JDK 6. -Joe From ted at tedneward.com Sun Aug 16 22:55:51 2009 From: ted at tedneward.com (Ted Neward) Date: Sun, 16 Aug 2009 22:55:51 -0700 Subject: Annotations for language features In-Reply-To: <4A88EC52.5050904@sun.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> <4A885B5D.8070905@sun.com> <00b001ca1ee8$60378e20$20a6aa60$@com> <4A88EC52.5050904@sun.com> Message-ID: <00d701ca1eff$6543db00$2fcb9100$@com> Dude, "getenv" was marked deprecated for a decade. :-) Seriously, I'm *not* trying to point fingers or cast blame, I'm just trying to point out that the messaging around a feature needs to be loud, clear, and unambiguous to avoid this kind of argument/debate/discussion later. Ted Neward Java, .NET, XML Services Consulting, Teaching, Speaking, Writing http://www.tedneward.com > -----Original Message----- > From: Joe.Darcy at Sun.COM [mailto:Joe.Darcy at Sun.COM] > Sent: Sunday, August 16, 2009 10:36 PM > To: Ted Neward > Cc: 'Adam Malter'; coin-dev at openjdk.java.net > Subject: Re: Annotations for language features > > Ted Neward wrote: > >> The apt tool and API was always planned to be "the one we throw > away" > >> in > >> the "The Mythical Man-Month" sense, which is why it has been > deprecated > >> in JDK 7 and is planned for removal in a future JDK release. > >> > >> > > In hindsight, that's easy to say; I don't remember any sort of > statement to > > that effect when it was first shipped. I'm not making accusations or > > > > First, the apt API is a com.sun.* API and not an official java or javax > API; second, since shipping in JDK 5 the apt javadoc has stated "Note > that the apt tool and its associated APIs may be changed or superseded > in future j2se releases:" > > http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/com/sun/mirror/apt > /package-summary.html > http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/com/sun/mirror/dec > laration/package-frame.html > http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/com/sun/mirror/typ > e/package-summary.html > http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/com/sun/mirror/uti > l/package-summary.html > > > espousing conspiracy theories, I just simply want to raise the idea > that apt > > was viewed by many--including me--as "the" Sun-blessed way to write > > annotation processors. > > > > It was in JDK 5 and ceased to be the recommended way to write > annotation > processors once JSR 269 shipped in JDK 6. > > -Joe From brucechapman at paradise.net.nz Mon Aug 17 02:48:17 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Mon, 17 Aug 2009 21:48:17 +1200 Subject: Annotations for language features In-Reply-To: References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> Message-ID: <4A892761.1030303@paradise.net.nz> > (quick: Name a java 1.5 language feature that could have > been done with annotations instead. I can't think of even one!) - but > where annotations fit, the AST building process does not have to > change at all - much easier for IDE developers. > > Just to be a pedantic off topic prick and answer your rhetorical question - it would have been way better if the annotation facility's "single element annotation" (where you omit the Identifier and = before the element value) had been designed to use an annotation to mark which element this applied to (rather than using the magic name "value") Bruce From Joe.Darcy at Sun.COM Mon Aug 17 17:37:16 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Mon, 17 Aug 2009 17:37:16 -0700 Subject: Annotations for language features In-Reply-To: <613a548a0908161311n1ee08ee9sb3388d7bcd99a710@mail.gmail.com> References: <15e8b9d20908091122haa51366n98d088fc5f0ae276@mail.gmail.com> <03d301ca1dda$c55ccdb0$50166910$@com> <91dd9a4f0908151738y1d077394k9257e1d36612061d@mail.gmail.com> <5275F44B-7D3F-4E63-BFB4-E24265C417DE@zwitserloot.com> <4A87BD44.4060406@adres.pl> <9435D53C-1073-40E2-8FBC-5C419393C8C1@zwitserloot.com> <4A884E96.2060108@adres.pl> <613a548a0908161145x40244501y8eef9fc9396df638@mail.gmail.com> <4A885B5D.8070905@sun.com> <613a548a0908161311n1ee08ee9sb3388d7bcd99a710@mail.gmail.com> Message-ID: <4A89F7BC.4010607@sun.com> Adam Malter wrote: > Joe - I apologize then, I read the tweaking of JSR 269 to be further > towards a new api than an evolution of the current. I did not mean to > spread mis-information. > > I will admit I am a bit gun shy about this issue, having to support a > com.sun.apt Processor, JSR 269 processor and Eclipse PlugIn (using > the eclipse ast) to enable some of the neat 'features' we want for > our implementation developers. > > Everything seems to work a bit differently depending on where and how > you compile. It's this lesson though that I wish to convey when I > express fear about core features enabled by code parsing and > generating in the JDK. Going slightly off-topic for the Project Coin list, one achievements of the JSR 269 API was that it was retrofitted without too much pain on two distinct long-lived compiler code bases and that the API was workable in both a batch and incremental setting. In Eclipse, the annotation processors are run on a per-file basis while in javac the round can encompass multiple files. This difference in behavior is allowed by the specification and a few API elements in JSR 269 were specifically added for the incremental/IDE setting: 1) Processor.getCompletions 2) The originatingElements arguments to the methods in the Filer The originating elements are passed in so the IDE can know what processors should be re-run to get a consistent set of build artifacts. To work well in either setting, the annotation processor author is expected to have some discipline in writing the processor: "To be robust when running in different tool implementations, an annotation processor should have the following properties: 1. The result of processing a given input is not a function of the presence or absence of other inputs (orthogonality). 2. Processing the same input produces the same output (consistency). 3. Processing input A followed by processing input B is equivalent to processing B then A (commutativity) 4. Processing an input does not rely on the presence of the output of other annotation processors (independence) " http://java.sun.com/javase/6/docs/api/javax/annotation/processing/Processor.html The JSR 269 expert group discussed the utility of having, say, an incremental Filer that would help provide infrastructure for incremental updates, but such facilities were not included as part of the reference implementation. I believe Bruce Chapman has made some progress in coding up this functionality. -Joe From Maurizio.Cimadamore at Sun.COM Fri Aug 21 11:07:22 2009 From: Maurizio.Cimadamore at Sun.COM (Maurizio Cimadamore) Date: Fri, 21 Aug 2009 19:07:22 +0100 Subject: diamond operator & implementation strategies (v3) Message-ID: <4A8EE25A.5030705@sun.com> Hi We have spent some time playing with the diamond operator[1, 6] - the result of this work are two different prototypes, one implementing the 'simple' strategy discussed in my earlier post[2, 3], another one implementing a more sophisticated approach that has been proposed by Neal [4,5] (in the remainder of this mail I'll refer to the latter as the 'complex' approach). The goal of this work has been to evaluate the impact of both strategies on existing code bases - in particular we were interested in knowing the fraction of constructors that could take advantage of the diamond operator and to see whether the two implementation strategies led to a significant difference w.r.t. the applicability of the new diamond operator. We have spent some more time performing benchmarks in order to evaluate both implementation strategies. The results produced by the two algorithms have been compared in order to check whether the inferred type was still applicable to the given site. More formally, let S be the generic type specified by the new expression in the pre-diamond code and T the type inferred by the diamond inference algorithm for that expression. There are 3 possible cases: a) T == S b) T != S, but T and S are interchangeable given the call site (e.g. because T is a subtype of S) c) T != S, with T and S not interchangeable a) and b) mean success, while c) means failure (the algorithm yields a result which is not equivalent to the explicit type specified by the programmer). In order to evaluate the fitness of a given implementation strategy, we have instrumented the two prototypes in order to emit detailed info about each new expression encountered by the compiler. In particular, for any given new expression whose target type is a generic type, both inference schemes have been applied and their results compared to the original generic type specified in the source code. The info generated by the two prototypes can be grouped into 3 categories (roughly corresponding to the classification above): *) "redundant" - this denotes a situation where generic type annotations can safely be removed from a new expression (see case (a,b) above). In order to provide more detailed info, We have splitted this category into two sub-categories: -) "redundant.normal" - this denotes a new expression appearing in an assignment context, more specifically where the type inferred by the diamond operator is a subtype of the expected type -) "redundant.no.context" - this denotes a new expression appearing in a place lacking of an assignment context, more specifically where the inferred type is a subtype of the original generic type *) "not.redundant" - this denotes a situation where there is no guarantee that removing generic type annotations from a new expression would yield to a sound expression (see case (c) above). In this case the inference algorithm exploited by the diamond operator has inferred a type T which is incompatible with both the expected type PT and the original type G (the one including generic type annotations). Note: it is possible that, by chance, the type inferred by the diamond operator would type-check where it is used (e.g. because that type is the type of an actual argument in a method call, where the corresponding formal is Object). *) "failure" - this denotes a failure of the inference algorithm. In this case it is definitively not possible to omit the generic type annotations, as the type inferred by the diamond operator is not valid (e.g. violates some constraints specified by the type-variables' declared bounds). Here's a brief summary of the statistics regarding the applicability of the diamond operator in three systems (see [7] for more detailed info): *** OpenJDK *** Overview: new expressions: 104138 new expressions w/ generic type: 5076 (4.87%) Results: redundant types (overall): simple 4409 (86.88%) / complex 4533 (89.30%) redundant (assignment): simple 4353 (85.76%) / complex 4352 (85.74%) redundant (other contexts: simple 56 (1.1%) / complex 181 (3.57%) non redundant: simple 662 (13.04%) / complex 536 (10.56%) failures: simple 4 (0.08%) / 7 (0.13%) *** Tomcat *** Overview: new expressions: 6048 new expressions w/ generic type: 153 (2.53%) Results: redundant types (overall): simple 148 (96.73%) / complex 148 (96.73%) redundant (assignment): simple 148 (96.73%) / complex 148 (96.73%) redundant (other contexts: simple 0 (0%) / complex 0 (0%) non redundant: simple 5 (3.38%) / complex 5 (3.38%) failures: simple 0 (0%) / complex 0 (0%) *** Netbeans *** Overview: new expressions: 94768 new expressions w/ generic type: 12010 (12.67%) Results: redundant types (overall): simple 10670 (88.84%) / complex 11085 (92.30%) redundant (assignment): simple 10628 (88.49%) / complex 10610 (88.34%) redundant (other contexts: simple 42 (0.35%) / complex 475 (3.96%) non redundant: simple 1338 (11.14%) / complex 907 (7.55%) failures: simple 2 (0.02%) / complex 18 (0.15%) The numbers are relatively stable across all benchmarks - to summarize, around 90% of all new expression whose target type is generic can be simplified using diamond (regardless of the chosen implementation strategy). The remaining 10% correspond to situations in which some type have been inferred - but there is no guarantee that the code would type-check (e.g. because the inferred type is not a subtype of the type in the code). No approach looks noticeably better than the other; the simple approach is weaker when it comes to infer types in an argument position - on the other hand the additional amount of types inferred by the complex approach is relatively low, and often the complex approach is less stable - that is there are more cases in which complex inference fails without inferring any type (this problem could be fixed, in principle, by improving standard javac type-inference, but such a task is outside the scope of the project Coin). The area in which the complex approach is stronger is where a class has recursive bounds; in such cases there's almost no way for the simple approach to infer a correct type, while the complex approach usually can rely on the type of some actual arguments in order to infer the right type (obviously this doesn't apply if the constructor is a no-arg constructor). Here's an example (extracted from OpenJDK): from DefaultMXBeanMappingFactory.java private static > MXBeanMapping makeEnumMapping(Class enumClass, Class fake) { return new EnumMapping(Util.>cast(enumClass)); //would work with complex but not with basic } [...] private static final class EnumMapping> [...] On the other hand there are situations in which the complex approach infers a type which is too specific and is thus incompatible with the LHS. Because of that, the amount of failures in the complex approach is slightly higher. Consider the following sample snippet (extracted from OpenJDK): from Snapshot.java private SoftReference finalizablesCache; [...] Vector finalizables = new Vector(); [...] finalizablesCache = new SoftReference(finalizables); //would work with basic but not with complex [...] As a final notice, it can be seen that collection classes are the 'killer app' for the diamond operator. Moreover the amount of raw constructor calls where the target type is a raw collection is relatively high across all benchmarks [7] (the 'most generified source' award goes to NetBeans). From our analysis, we conclude that the simple approach should be preferred, as the extra complexity required by the complex approach does not entirely pay off. As said above, this is because the scope of javac's method type inference is limited (e.g. no return type-inference is applied when a generic method call occur in argument position). Because of that, the complex approach is able to deliver only a small improvement over a simpler and straightforward approach. Moreover, our initial concerns about code refactoring seem to be confirmed by the numbers given in the benchmarks - it is possible to notice how, across all benchmark, the simple approach gives better results in straight assignment contexts (except for the Tomcat benchmark, where the two prototypes give the same results). In order to improve the behavior of the complex approach in assignment contexts some non-trivial changes to javac's method type inference are required (e.g. perform a single round of type inference where all constraints - formals and return type - are considered at once). Again, such changes are risky, and definitively outside the scope of project Coin. Here's a brief outline of the JLS changes that would be required in order to support the simple approach: 15.9 (grammar) This production: "ClassBodyopt: Primary. new TypeArgumentsopt Identifier TypeArgumentsopt (ArgumentListopt) ClassBodyopt" Should be changed as follows: "ClassOrInterfaceType: Primary. new TypeArgumentsopt Identifier TypeArgumentsOrDiamondopt (ArgumentListopt) ClassBodyopt TypeArgumentsOrDiamondopt: TypeArguments <>" Moreover, section 15.9.1 (Determining the Class being Instantiated) should be adjusted so that the following paragraph is added: "If the type denoted by ClassOrInterfaceType has an empty type argument list (diamond operator), then the following steps must be applied in order to infer the actual type of the class being instantiated: *) Let C be the name of the (generic) class being instantiated, and X1, X2... Xn the formal type arguments declared by class C. Moreover, if the instance creation expression occurs in a context where it will be subject to assignment conversion (?5.2) to a type S, then let G be C, *) Consider the following initial set of constraints: * the constraint S >> G * additional constraints Bi >> Ti, where Bi is the declared bound of Xi, *) The above constaints are used to infer constraints on the type arguments using the algorithm of section (?15.12.2.7). Any equality constraints are resolved, and then, for each remaining constraint of the form Xi <: Uk, the argument Xi is inferred to be glb(U1, ..., Uk) (?5.1.10). Any remaining type variables that have not yet been inferred are then inferred to have type Object" [1] http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000009.html [2] http://mail.openjdk.java.net/pipermail/coin-dev/2009-May/001720.html [3] http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.0/ [4] http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000075.html [5] http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/ [6] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6840638 [7] http://blogs.sun.com/mcimadamore/resource/diamonds_statistics.pdf Maurizio From Joe.Darcy at Sun.COM Fri Aug 21 11:10:47 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 21 Aug 2009 11:10:47 -0700 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <4A8EE25A.5030705@sun.com> References: <4A8EE25A.5030705@sun.com> Message-ID: <4A8EE327.1070304@sun.com> Maurizio Cimadamore wrote: > Hi > We have spent some time playing with the diamond operator[1, 6] - the > result of this work are two different prototypes, one implementing the > 'simple' strategy discussed in my earlier post[2, 3], another one > implementing a more sophisticated approach that has been proposed by > Neal [4,5] (in the remainder of this mail I'll refer to the latter as > the 'complex' approach). > Thanks Maurizio for that good work on diamond! Please send comments on the feature to the list. Maurizio will be away for a while and discussion can continue on the list until he can participate again. In other news, I plan to announce the final list of candidate features within the next week or so. I also plan to finish work on the prototype for strings in switch in the coming weeks. -Joe From neal at gafter.com Fri Aug 21 12:12:56 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 21 Aug 2009 12:12:56 -0700 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <4A8EE25A.5030705@sun.com> References: <4A8EE25A.5030705@sun.com> Message-ID: <15e8b9d20908211212q688ff56cs4380be7bd0f920b2@mail.gmail.com> A significant benefit of the "complex" approach is that it interacts nicely with possible future support for inference in argument positions. The "simple" approach cannot be extended in a straightforward way to interact nicely with inference in argument positions. If this is indeed the end of the line of the evolution of the Java programming language, then this particular choice doesn't matter much. On the other hand, if future evolution is likely, then an approach that supports evolution is to be preferred. On Fri, Aug 21, 2009 at 11:07 AM, Maurizio Cimadamore < Maurizio.Cimadamore at sun.com> wrote: > Hi > We have spent some time playing with the diamond operator[1, 6] - the > result of this work are two different prototypes, one implementing the > 'simple' strategy discussed in my earlier post[2, 3], another one > implementing a more sophisticated approach that has been proposed by > Neal [4,5] (in the remainder of this mail I'll refer to the latter as > the 'complex' approach). > > The goal of this work has been to evaluate the impact of both strategies > on existing code bases - in particular we were interested in knowing the > fraction of constructors that could take advantage of the diamond > operator and to see whether the two implementation strategies led to a > significant difference w.r.t. the applicability of the new diamond > operator. > > We have spent some more time performing benchmarks in order to evaluate > both implementation strategies. The results produced by the two > algorithms have been compared in order to check whether the inferred > type was still applicable to the given site. More formally, let S be the > generic type specified by the new expression in the pre-diamond code and > T the type inferred by the diamond inference algorithm for that > expression. There are 3 possible cases: > > a) T == S > b) T != S, but T and S are interchangeable given the call site (e.g. > because T is a subtype of S) > c) T != S, with T and S not interchangeable > > a) and b) mean success, while c) means failure (the algorithm yields a > result which is not equivalent to the explicit type specified by the > programmer). In order to evaluate the fitness of a given implementation > strategy, we have instrumented the two prototypes in order to emit > detailed info about each new expression encountered by the compiler. In > particular, for any given new expression whose target type is a generic > type, both inference schemes have been applied and their results > compared to the original generic type specified in the source code. The > info generated by the two prototypes can be grouped into 3 categories > (roughly corresponding to the classification above): > > *) "redundant" - this denotes a situation where generic type annotations > can safely be removed from a new expression (see case (a,b) above). In > order to provide more detailed info, We have splitted this category into > two sub-categories: > > -) "redundant.normal" - this denotes a new expression appearing in an > assignment context, more specifically where the type inferred by the > diamond operator is a subtype of the expected type > > -) "redundant.no.context" - this denotes a new expression appearing in a > place lacking of an assignment context, more specifically where the > inferred type is a subtype of the original generic type > > *) "not.redundant" - this denotes a situation where there is no > guarantee that removing generic type annotations from a new expression > would yield to a sound expression (see case (c) above). In this case the > inference algorithm exploited by the diamond operator has inferred a > type T which is incompatible with both the expected type PT and the > original type G (the one including generic type annotations). Note: it > is possible that, by chance, the type inferred by the diamond operator > would type-check where it is used (e.g. because that type is the type of > an actual argument in a method call, where the corresponding formal is > Object). > > *) "failure" - this denotes a failure of the inference algorithm. In > this case it is definitively not possible to omit the generic type > annotations, as the type inferred by the diamond operator is not valid > (e.g. violates some constraints specified by the type-variables' > declared bounds). > > Here's a brief summary of the statistics regarding the applicability of > the diamond operator in three systems (see [7] for more detailed info): > > *** OpenJDK *** > > Overview: > > new expressions: 104138 > new expressions w/ generic type: 5076 (4.87%) > > Results: > > redundant types (overall): simple 4409 (86.88%) / complex 4533 (89.30%) > redundant (assignment): simple 4353 (85.76%) / complex 4352 (85.74%) > redundant (other contexts: simple 56 (1.1%) / complex 181 (3.57%) > non redundant: simple 662 (13.04%) / complex 536 (10.56%) > failures: simple 4 (0.08%) / 7 (0.13%) > > *** Tomcat *** > > Overview: > > new expressions: 6048 > new expressions w/ generic type: 153 (2.53%) > > Results: > > redundant types (overall): simple 148 (96.73%) / complex 148 (96.73%) > redundant (assignment): simple 148 (96.73%) / complex 148 (96.73%) > redundant (other contexts: simple 0 (0%) / complex 0 (0%) > non redundant: simple 5 (3.38%) / complex 5 (3.38%) > failures: simple 0 (0%) / complex 0 (0%) > > *** Netbeans *** > > Overview: > > new expressions: 94768 > new expressions w/ generic type: 12010 (12.67%) > > Results: > > redundant types (overall): simple 10670 (88.84%) / complex 11085 (92.30%) > redundant (assignment): simple 10628 (88.49%) / complex 10610 (88.34%) > redundant (other contexts: simple 42 (0.35%) / complex 475 (3.96%) > non redundant: simple 1338 (11.14%) / complex 907 (7.55%) > failures: simple 2 (0.02%) / complex 18 (0.15%) > > > > The numbers are relatively stable across all benchmarks - to summarize, > around 90% of all new expression whose target type is generic can be > simplified using diamond (regardless of the chosen implementation > strategy). The remaining 10% correspond to situations in which some type > have been inferred - but there is no guarantee that the code would > type-check (e.g. because the inferred type is not a subtype of the type > in the code). > > No approach looks noticeably better than the other; the simple approach > is weaker when it comes to infer types in an argument position - on the > other hand the additional amount of types inferred by the complex > approach is relatively low, and often the complex approach is less > stable - that is there are more cases in which complex inference fails > without inferring any type (this problem could be fixed, in principle, > by improving standard javac type-inference, but such a task is outside > the scope of the project Coin). > > The area in which the complex approach is stronger is where a class has > recursive bounds; in such cases there's almost no way for the simple > approach to infer a correct type, while the complex approach usually can > rely on the type of some actual arguments in order to infer the right > type (obviously this doesn't apply if the constructor is a no-arg > constructor). Here's an example (extracted from OpenJDK): > > from DefaultMXBeanMappingFactory.java > > private static > MXBeanMapping > makeEnumMapping(Class enumClass, Class fake) { > return new EnumMapping(Util.>cast(enumClass)); > //would work with complex but not with basic > } > > [...] > > private static final class EnumMapping> [...] > > > On the other hand there are situations in which the complex approach > infers a type which is too specific and is thus incompatible with the > LHS. Because of that, the amount of failures in the complex approach is > slightly higher. Consider the following sample snippet (extracted from > OpenJDK): > > from Snapshot.java > > private SoftReference finalizablesCache; > > [...] > > Vector finalizables = new Vector(); > > [...] > > finalizablesCache = new SoftReference(finalizables); //would > work with basic but not with complex > > [...] > > > As a final notice, it can be seen that collection classes are the > 'killer app' for the diamond operator. Moreover the amount of raw > constructor calls where the target type is a raw collection is > relatively high across all benchmarks [7] (the 'most generified source' > award goes to NetBeans). > > > > From our analysis, we conclude that the simple approach should be > preferred, as the extra complexity required by the complex approach does > not entirely pay off. As said above, this is because the scope of > javac's method type inference is limited (e.g. no return type-inference > is applied when a generic method call occur in argument position). > Because of that, the complex approach is able to deliver only a small > improvement over a simpler and straightforward approach. Moreover, our > initial concerns about code refactoring seem to be confirmed by the > numbers given in the benchmarks - it is possible to notice how, across > all benchmark, the simple approach gives better results in straight > assignment contexts (except for the Tomcat benchmark, where the two > prototypes give the same results). In order to improve the behavior of > the complex approach in assignment contexts some non-trivial changes to > javac's method type inference are required (e.g. perform a single round > of type inference where all constraints - formals and return type - are > considered at once). Again, such changes are risky, and definitively > outside the scope of project Coin. > > Here's a brief outline of the JLS changes that would be required in > order to support the simple approach: > > 15.9 (grammar) > > This production: > > "ClassBodyopt: > Primary. new TypeArgumentsopt Identifier TypeArgumentsopt > (ArgumentListopt) ClassBodyopt" > > Should be changed as follows: > > "ClassOrInterfaceType: > Primary. new TypeArgumentsopt Identifier > TypeArgumentsOrDiamondopt (ArgumentListopt) ClassBodyopt > > TypeArgumentsOrDiamondopt: TypeArguments > <>" > > > Moreover, section 15.9.1 (Determining the Class being Instantiated) > should be adjusted so that the following paragraph is added: > > "If the type denoted by ClassOrInterfaceType has an empty type argument > list (diamond operator), then the following steps must be applied in > order to infer the actual type of the class being instantiated: > > *) Let C be the name of the (generic) class being instantiated, and X1, > X2... Xn the formal type arguments declared by class C. Moreover, if the > instance creation expression occurs in a context where it will be > subject to assignment conversion (?5.2) to a type S, then let G be C X2 ... Xn>, > > *) Consider the following initial set of constraints: > > * the constraint S >> G > * additional constraints Bi >> Ti, where Bi is the declared bound > of Xi, > > *) The above constaints are used to infer constraints on the type > arguments using the algorithm of section (?15.12.2.7). Any equality > constraints are resolved, and then, for each remaining constraint of the > form Xi <: Uk, the argument Xi is inferred to be glb(U1, ..., Uk) > (?5.1.10). > > Any remaining type variables that have not yet been inferred are then > inferred to have type Object" > > [1] > http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000009.html > [2] http://mail.openjdk.java.net/pipermail/coin-dev/2009-May/001720.html > [3] http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.0/ > [4] http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000075.html > [5] http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/ > [6] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6840638 > [7] http://blogs.sun.com/mcimadamore/resource/diamonds_statistics.pdf > > Maurizio > > > > > From pbenedict at apache.org Fri Aug 21 12:54:53 2009 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 21 Aug 2009 14:54:53 -0500 Subject: diamond operator & implementation strategies (v3) Message-ID: Maurizio and all, Do you believe that the "simple approach" is a subset of the "complex approach"? For the changes recommended regarding the JLS, I hope they would nicely pave the way for the complex approach later on. It would be a shame if these type-inference rules cornered javac from later expanding its rules. Paul From neal at gafter.com Fri Aug 21 21:29:36 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 21 Aug 2009 21:29:36 -0700 Subject: diamond operator & implementation strategies (v3) In-Reply-To: References: Message-ID: <15e8b9d20908212129n1f0835dm38ec8a487d2c2c0d@mail.gmail.com> I believe there are situations that they give different, incompatible results. The "complex" method is currently (Java 5 and later) used for inference of method type arguments, so the language and compiler must implement it already. I feel it's better to have one inference algorithm rather than two. On Fri, Aug 21, 2009 at 12:54 PM, Paul Benedict wrote: > Maurizio and all, > > Do you believe that the "simple approach" is a subset of the "complex > approach"? For the changes recommended regarding the JLS, I hope they would > nicely pave the way for the complex approach later on. It would be a shame > if these type-inference rules cornered javac from later expanding its > rules. > > Paul > > From scolebourne at joda.org Sat Aug 22 02:32:34 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 22 Aug 2009 10:32:34 +0100 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <15e8b9d20908212129n1f0835dm38ec8a487d2c2c0d@mail.gmail.com> References: <15e8b9d20908212129n1f0835dm38ec8a487d2c2c0d@mail.gmail.com> Message-ID: <4A8FBB32.6000309@joda.org> Funnily enough, my first question given there was a choice of options was which would be better for the future. So far, I'm hearing "complex", so my vote would currently tend that way. Stephen Neal Gafter wrote: > I believe there are situations that they give different, incompatible > results. The "complex" method is currently (Java 5 and later) used for > inference of method type arguments, so the language and compiler must > implement it already. I feel it's better to have one inference algorithm > rather than two. > > On Fri, Aug 21, 2009 at 12:54 PM, Paul Benedict wrote: > >> Maurizio and all, >> >> Do you believe that the "simple approach" is a subset of the "complex >> approach"? For the changes recommended regarding the JLS, I hope they would >> nicely pave the way for the complex approach later on. It would be a shame >> if these type-inference rules cornered javac from later expanding its >> rules. >> >> Paul >> >> > > From Maurizio.Cimadamore at Sun.COM Sat Aug 22 03:20:34 2009 From: Maurizio.Cimadamore at Sun.COM (Maurizio Cimadamore) Date: Sat, 22 Aug 2009 11:20:34 +0100 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <15e8b9d20908212129n1f0835dm38ec8a487d2c2c0d@mail.gmail.com> References: <15e8b9d20908212129n1f0835dm38ec8a487d2c2c0d@mail.gmail.com> Message-ID: <4A8FC672.70206@sun.com> Neal Gafter wrote: > I believe there are situations that they give different, incompatible > results. The "complex" method is currently (Java 5 and later) used for > inference of method type arguments, so the language and compiler must > implement it already. I feel it's better to have one inference algorithm > rather than two. > Hi Neal (and others) I'd like to provide a couple of clarifications; let's start with the easy one (implementation): javac's type inference (and JLS type-inference, in general) is made up of two *mostly independent* steps: *) inference from actual vs. formal arguments (see JLS 15.12.2.7) *) inference from return type vs. expected type (see JLS 15.12.2.8) In Javac these two steps are unrelated, as the first one (actual vs. formal) is performed during method resolution (that is when javac has to find a method symbol that is suitable for a given call site); the latter step is performed at a later point, when the result type of the method is checked against the expected type (caveat: this step is actually skipped if there's no expected type). As you can see from the code, both approaches tend to reuse a lot of what is already available in the compiler internals - that's also why the patches are not so big, in terms of line of code. The simple approach only applies the second step of javac's type inference (which is a call to Infer.instantiateExpr). No new 'inference' code is required in order to implement that approach. On the other hand, the complex approach needs both steps (which means a call to Infer.instantiateMethod followed by an indirect call to Infer.instantiateExpr). Bottom line: both approaches re-use what is already available inside the compiler. Why is the complex approach 'complex' ? The complex approach requires a 'fake' constructor symbol to be synthetized by the compiler. This constructor should replace all the class type variables with 'holes' that can be filled during the inference process. In other words, the complex approach doesn't work on the class as it is in the source code; it requires a source transformation - so that, e.g. the following constructor: class Foo { Foo(X x) { ... } } gets rewritten as follows: translated_foo_constr Foo (X x) { ... } [The actual implementation is optimized, so that no source translation occurs - the compiler just adds synthetic symbols to the current class, so that the resolution process can succeed]. The difference between the two approaches is that with the simple approach the compiler can discover the type of the class to be instantiated earlier in the process - that is, w/o having to apply a method resolution round. With the complex approach, on the other hand, it's impossible to say which classtype will be instantiated before method resolution takes place. We believe that this subtle difference is what makes the simple approach more compelling and more in spirit with the Java language. About evolution: the simple approach is not a proper subset of the complex approach - which means that the results given by the two algorithms may vary (even if not too often as the benchmarks show). As I said there are situations in which one approach is better than the other, and vice-versa. However both approaches are a proper subset of what I should call 'full complex' approach - which is essentially a complex approach on steroids (that is augmented with some javac type-inference changes). Let's rivisit the two examples of my earlier email in order to see if the 'full-complex' approach has an answer to both of them: from DefaultMXBeanMappingFactory.java private static > MXBeanMapping makeEnumMapping(Class enumClass, Class fake) { return new EnumMapping(Util.>cast(enumClass)); //would work with complex but not with basic } [...] private static final class EnumMapping> [...] In this case the 'full-complex' approach will obviously win - as the actual argument type would be used in ordet to infer T'==Class (simple approach alone would fail because of the recursive bound on T). The other example was: from Snapshot.java private SoftReference finalizablesCache; [...] Vector finalizables = new Vector(); [...] finalizablesCache = new SoftReference(finalizables); //would work with basic but not with complex [...] Which used to fail with complex, as it inferred a type not compatible with the LHS - if we could join the two type-inference steps described above so to throw the method return type at inference earlier in the process, we would have an additional constraint added to the inference algorithm that would force the compiler to come up with a type compatible with the LHS (SoftReference). In other words the two approaches are currently not fully compatible because they are both (in their own way) incomplete. Which also means that they both can be subsumed by a more complete approach that is able to join the advantages of both approaches. Maurizio > On Fri, Aug 21, 2009 at 12:54 PM, Paul Benedict wrote: > > >> Maurizio and all, >> >> Do you believe that the "simple approach" is a subset of the "complex >> approach"? For the changes recommended regarding the JLS, I hope they would >> nicely pave the way for the complex approach later on. It would be a shame >> if these type-inference rules cornered javac from later expanding its >> rules. >> >> Paul >> >> >> > > From pbenedict at apache.org Sat Aug 22 10:43:09 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sat, 22 Aug 2009 12:43:09 -0500 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <4A8FC672.70206@sun.com> References: <15e8b9d20908212129n1f0835dm38ec8a487d2c2c0d@mail.gmail.com> <4A8FC672.70206@sun.com> Message-ID: Maurizio, Great response. Thank you. I am going to infer (pun) the 'full-complex' approach is outside the scope of Project Coin. Since it seems the 'simple' approach has your favor, my advice for you is to apply great caution to the JLS changes as to make them forward-compatible. Any inference must be identically solved by the 'full-complex' approach, otherwise it shouldn't be inferred. I think it would be a bad idea for call sites to get resolved successfully (and differently) between Java 7 and Java 8+. Paul From forax at univ-mlv.fr Sat Aug 22 14:32:22 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 22 Aug 2009 23:32:22 +0200 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <4A8EE25A.5030705@sun.com> References: <4A8EE25A.5030705@sun.com> Message-ID: <4A9063E6.5010506@univ-mlv.fr> Le 21/08/2009 20:07, Maurizio Cimadamore a ?crit : > Hi > Hi Maurizio, [...] > On the other hand there are situations in which the complex approach > infers a type which is too specific and is thus incompatible with the > LHS. Because of that, the amount of failures in the complex approach is > slightly higher. Consider the following sample snippet (extracted from > OpenJDK): > > from Snapshot.java > > private SoftReference finalizablesCache; > > [...] > > Vector finalizables = new Vector(); > > [...] > > finalizablesCache = new SoftReference(finalizables); //would > work with basic but not with complex > > [...] > > > As a final notice, it can be seen that collection classes are the > 'killer app' for the diamond operator. Moreover the amount of raw > constructor calls where the target type is a raw collection is > relatively high across all benchmarks [7] (the 'most generified source' > award goes to NetBeans). > Just a question, is there code that fails with the complex inference algorithm that doesn't involve raw type/rare type ? [...] > Maurizio > R?mi From Maurizio.Cimadamore at Sun.COM Mon Aug 24 01:46:51 2009 From: Maurizio.Cimadamore at Sun.COM (Maurizio Cimadamore) Date: Mon, 24 Aug 2009 09:46:51 +0100 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <4A9063E6.5010506@univ-mlv.fr> References: <4A8EE25A.5030705@sun.com> <4A9063E6.5010506@univ-mlv.fr> Message-ID: <4A92537B.5090600@sun.com> > > > Just a question, is there code that fails with the complex inference > algorithm > that doesn't involve raw type/rare type ? > Hi Remi, to summarize, the complex approach can have problems when dealing with no arg constructors (quite common esp. with collections, see HashMap, ArrayList, ...) In this case, the complex approach yields the same result given by the simple approach, as no inference from formals is possible: class Foo { Foo() {} static void m(Foo fi) { ... } } m(new Foo<>()); //fails with both simple and complex Another problematic situation can arise when the RHS type parameters are less specific than the actual arguments passed to the constructor: class Foo { Foo(X x) {} } Foo fn = new Foo<>(1); //simple succeeds (X==Number) - complex fails (X==Integer != Number). Maurizio > [...] > > >> Maurizio >> >> > > R?mi > > From forax at univ-mlv.fr Mon Aug 24 18:04:06 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Tue, 25 Aug 2009 03:04:06 +0200 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <4A92537B.5090600@sun.com> References: <4A8EE25A.5030705@sun.com> <4A9063E6.5010506@univ-mlv.fr> <4A92537B.5090600@sun.com> Message-ID: <4A933886.2040901@univ-mlv.fr> Le 24/08/2009 10:46, Maurizio Cimadamore a ?crit : > >> >> >> Just a question, is there code that fails with the complex inference >> algorithm >> that doesn't involve raw type/rare type ? > Hi Remi, > to summarize, the complex approach can have problems when dealing with > no arg constructors (quite common esp. with collections, see HashMap, > ArrayList, ...) > > In this case, the complex approach yields the same result given by the > simple approach, as no inference from formals is possible: > > class Foo { > Foo() {} > static void m(Foo fi) { ... } > } > > m(new Foo<>()); //fails with both simple and complex > no arg constructor in method call => problem. Correct me if I'm wrong but currently inference of method type parameters also fails. So It's not a big deal. > Another problematic situation can arise when the RHS type parameters > are less specific than the actual arguments passed to the constructor: > > class Foo { > Foo(X x) {} > } > > Foo fn = new Foo<>(1); //simple succeeds (X==Number) - complex > fails (X==Integer != Number). This example also fails in case of inference of method type parameter. I think I prefer the complex inference algorithm because it works like the current method inference. And in jdk8, we will see how to introduce the "complex on steroid" algorithm for both method and constructor inference. R?mi From neal at gafter.com Mon Aug 24 18:20:11 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 24 Aug 2009 18:20:11 -0700 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <4A933886.2040901@univ-mlv.fr> References: <4A8EE25A.5030705@sun.com> <4A9063E6.5010506@univ-mlv.fr> <4A92537B.5090600@sun.com> <4A933886.2040901@univ-mlv.fr> Message-ID: <15e8b9d20908241820g60bc6a92lc484a597a62e4039@mail.gmail.com> On Mon, Aug 24, 2009 at 6:04 PM, R?mi Forax wrote: > no arg constructor in method call => problem. > Correct me if I'm wrong but currently inference of method type > parameters also fails. > So It's not a big deal. Agreed. What Maurizio calls the "complex" diamond inference approach is actually the existing generic method inference algorithm, but applied to constructors. I prefer to call it the "compatible" algorithm. The current method type inference has a straightforward extension to handle argument contexts that I expect is likely to be considered for a future extension. It was actually in some late JSR14 prototypes, but removed in the latest versions due to concerns about the alignment of the spec and the implementation. The compatible algorithm would naturally get the benefits of any improvement to method inference, including for argument contexts. The "simple" version, on the other hand, does not have a straightforward extension to inference in argument contexts. In short, it mainly a big deal if the future evolution of the language is considered. The main reason that I've heard for preferring the "simple" algorithm is that it is simpler. How many lines of code were required for each approach? Now that both algorithms have been implemented that should hardly be much of a consideration, but it would be nice to know. -Neal From Maurizio.Cimadamore at Sun.COM Tue Aug 25 01:52:09 2009 From: Maurizio.Cimadamore at Sun.COM (Maurizio Cimadamore) Date: Tue, 25 Aug 2009 09:52:09 +0100 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <15e8b9d20908241820g60bc6a92lc484a597a62e4039@mail.gmail.com> References: <4A8EE25A.5030705@sun.com> <4A9063E6.5010506@univ-mlv.fr> <4A92537B.5090600@sun.com> <4A933886.2040901@univ-mlv.fr> <15e8b9d20908241820g60bc6a92lc484a597a62e4039@mail.gmail.com> Message-ID: <4A93A639.8000805@sun.com> Neal Gafter wrote: > On Mon, Aug 24, 2009 at 6:04 PM, R?mi Forax wrote: > > >> no arg constructor in method call => problem. >> Correct me if I'm wrong but currently inference of method type >> parameters also fails. >> So It's not a big deal. >> > > @Remi: it's true, the complex approach has a similar behavior to javac's type inference. But to be honest I don't entirely understand your argument - since javac's type-inference is limited (some paper even say broken[1] ;-) ) you'd prefer a diamond inference scheme which is equally ''broken''. Apart from jokes, I think we are talking at different levels here: you are all very expert JDK/javac developers - you know every possible inference corner case, so that any failure looks familiar to you, because you know the rules of the game. Choosing the simple approach is not about choosing the easiest path (see below) - it's first and foremost about optimizing the most frequent use case which is: GenericVarType Ident = new GenericVarType(...); This is what a client of the diamond feature expects diamond to be good at; and currently the complex approach is not able to deliver in this particular use case - as we said javac's type inference is to blame for that - but nevertheless I think it's important that we deliver something that people can intuitively use. How do you think people is going to explain why this can be refactored: Foo fi = new Foo<>(1); while the following cannot: Foo fn = new Foo<>(1); A developer who is familiar with inference problem will immediately spot the problem and think (as Remi did): well - it's type-inference that falls short here. But I don't expect this level of expertize to be the norm. Some people will think that the feature is broken and they will come back at us claiming that we should fix this. @Neal: about simplicity; I totally disagree with the implicit statement that (i) the simple approach is the easiest path (see above) and (ii) that simplicity corresponds to the amount of lines of code in a patch. I haven't compared the two patches (they are linked at the bottom of my original mail[2] if you are interested in doing so) - on my part I can just say that they look pretty similar to me in terms of LOC - with one fundamental difference: the simple approach doesn't mess around with scope and resolution (and doesn't have to). I dubbed the 'simple' approach this way because of the impact it has on the existing language. In an earlier mail[3] I provided details about why I think the complex approach is 'complex'. And btw, it took me a couple of days in order to implement each - so it's not about time either :-) [1] http://www.cs.rice.edu/%7Edlsmith/java-type-system-oopsla08.pdf [2] http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002159.html [3] http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html Maurizio > Agreed. > > What Maurizio calls the "complex" diamond inference approach is actually the > existing generic method inference algorithm, but applied to constructors. I > prefer to call it the "compatible" algorithm. The current method type > inference has a straightforward extension to handle argument contexts that I > expect is likely to be considered for a future extension. It was actually > in some late JSR14 prototypes, but removed in the latest versions due to > concerns about the alignment of the spec and the implementation. The > compatible algorithm would naturally get the benefits of any improvement to > method inference, including for argument contexts. The "simple" version, on > the other hand, does not have a straightforward extension to inference in > argument contexts. > > In short, it mainly a big deal if the future evolution of the language is > considered. > > The main reason that I've heard for preferring the "simple" algorithm is > that it is simpler. How many lines of code were required for each > approach? Now that both algorithms have been implemented that should hardly > be much of a consideration, but it would be nice to know. > > -Neal > > From forax at univ-mlv.fr Tue Aug 25 06:23:09 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Tue, 25 Aug 2009 15:23:09 +0200 Subject: diamond operator & implementation strategies (v3) In-Reply-To: <4A93A639.8000805@sun.com> References: <4A8EE25A.5030705@sun.com> <4A9063E6.5010506@univ-mlv.fr> <4A92537B.5090600@sun.com> <4A933886.2040901@univ-mlv.fr> <15e8b9d20908241820g60bc6a92lc484a597a62e4039@mail.gmail.com> <4A93A639.8000805@sun.com> Message-ID: <4A93E5BD.5000401@univ-mlv.fr> Le 25/08/2009 10:52, Maurizio Cimadamore a ?crit : > Neal Gafter wrote: >> On Mon, Aug 24, 2009 at 6:04 PM, R?mi Forax wrote: >> >>> no arg constructor in method call => problem. >>> Correct me if I'm wrong but currently inference of method type >>> parameters also fails. >>> So It's not a big deal. >> > @Remi: it's true, the complex approach has a similar behavior to > javac's type inference. But to be honest I don't entirely understand > your argument - since javac's type-inference is limited (some paper > even say broken[1] ;-) ) you'd prefer a diamond inference scheme which > is equally ''broken''. Yes, I prefer only one algorithm broken instead of two. It's simpler for the future, after jdk7, we will have to fix only one algorithm, not two. > > Apart from jokes, I think we are talking at different levels here: you > are all very expert JDK/javac developers - you know every possible > inference corner case, so that any failure looks familiar to you, > because you know the rules of the game. I don't think I know every corner cases :) I use the 'teaching' metric. If you introduce a new algorithm for diamond, I will have to teach it, and explain why it's different from the one used for method inference so it will complexify something that is already not that simple. > > Choosing the simple approach is not about choosing the easiest path > (see below) - it's first and foremost about optimizing the most > frequent use case which is: > > GenericVarType Ident = new GenericVarType(...); > > This is what a client of the diamond feature expects diamond to be > good at; and currently the complex approach is not able to deliver in > this particular use case - as we said javac's type inference is to > blame for that - but nevertheless I think it's important that we > deliver something that people can intuitively use. > > How do you think people is going to explain why this can be refactored: > > Foo fi = new Foo<>(1); > > while the following cannot: > > Foo fn = new Foo<>(1); I already explain it because it's how the current method inference works. I have to explain why Foo fn = Foo.create(1); works but not Foo fn = Foo.create(1); So in my opinion, it's more simple to say 1) diamond works like method inference 2) the inference algorithm is sometimes broken but we will improve it. To summarize, I don't see why you want that constructor inference work differently from method inference. > > A developer who is familiar with inference problem will immediately > spot the problem and think (as Remi did): well - it's type-inference > that falls short here. But I don't expect this level of expertize to > be the norm. Some people will think that the feature is broken and > they will come back at us claiming that we should fix this. People already think that method inference is broken, and there are right. We know we will have to provide a fix for method inference. So when this fix will be available, it will fix the diamond syntax too. > > @Neal: about simplicity; I totally disagree with the implicit > statement that (i) the simple approach is the easiest path (see above) > and (ii) that simplicity corresponds to the amount of lines of code in > a patch. I haven't compared the two patches (they are linked at the > bottom of my original mail[2] if you are interested in doing so) - on > my part I can just say that they look pretty similar to me in terms of > LOC - with one fundamental difference: the simple approach doesn't > mess around with scope and resolution (and doesn't have to). I dubbed > the 'simple' approach this way because of the impact it has on the > existing language. In an earlier mail[3] I provided details about why > I think the complex approach is 'complex'. And btw, it took me a > couple of days in order to implement each - so it's not about time > either :-) > [1] http://www.cs.rice.edu/%7Edlsmith/java-type-system-oopsla08.pdf > [2] > http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002159.html > [3] > http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html > > Maurizio R?mi From Joe.Darcy at Sun.COM Fri Aug 28 17:44:51 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 28 Aug 2009 17:44:51 -0700 Subject: The Final Five (or so) Message-ID: <4A987A03.7040403@sun.com> First, thanks to all those who submitted interesting proposals and thoughtful comments to Project Coin; a demonstrably vibrant community wants to evolve the Java programming language! Without further ado, the final Project Coin changes accepted for inclusion in JDK 7 are: * Strings in switch * Automatic Resource Management * Improved Type Inference for Generic Instance Creation (diamond) * Simplified Varargs Method Invocation * An omnibus proposal for better integral literals * Language support for Collections * Language support for JSR 292 The specification, implementation, and testing of these changes are not final and will continue to evolve as interactions are explored and issues cleared. Two of the listed items are combinations of multiple submitted proposals. The omnibus proposal for improved integer literals includes at least binary literals and underscores in numbers; a way to better handle unsigned literals is desired too. Language support for Collections covers collection literals and allows for developing indexing access for Lists and Maps, assuming the technical problems are resolved. That leaves a few proposals that went through further consideration, but were not accepted on the final list: * Improved Exception Handling for Java * Elvis and Other Null-Safe Operators * Large arrays Improved exception handling would be a fine change for the language, but it ventures near the type system and we do not estimate we have resources to fully develop the feature within JDK 7. I would like to see improved exception handling reconsidered in subsequent efforts to evolve the language. While the Elvis operator and related operators are helpful in Groovy, differences between Groovy and Java, such as the presence of primitive types and interactions with boxing/unboxing render the operators less useful in Java. JDK 7 will support other ways to ease the pain of null-handling, such as the null checking enabled by JSR 308. Aggregates natively supporting more than 32-bits worth of entries will no doubt be increasingly needed over time. Language support for collections may allow such facilities to be developed as libraries until the platform directly handles large data structures. The coin-dev list will remain available for the continued refinement of the accepted changes. Further discussion of proposals not selected is off-topic for the list. The majority of the implementation of the Project Coin changes should be in JDK 7's development Mercurial repositories by the end of October 2009. In due course, we intend to file a JSR covering the Project Coin changes. From pdoubleya at gmail.com Sat Aug 29 05:44:30 2009 From: pdoubleya at gmail.com (Patrick Wright) Date: Sat, 29 Aug 2009 14:44:30 +0200 Subject: The Final Five (or so) In-Reply-To: <4A987A03.7040403@sun.com> References: <4A987A03.7040403@sun.com> Message-ID: <64efa1ba0908290544q28f46b61q2d47b7827bd9b465@mail.gmail.com> Joe Thanks for opening the language-enhancement process to outside input and discussion. Sad to see the occasional negativity aimed that resulted in the discussion, but very glad that we were all able to follow the process as it developed. You did a great job moderating the discussion, IMO. Kudos. Regards Patrick From pbenedict at apache.org Sun Aug 30 22:53:18 2009 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 31 Aug 2009 00:53:18 -0500 Subject: The Final Five (or so) Message-ID: I am hoping the "JSR-292 language support" does not include the # syntax. I think that's a very poor syntax since, I believe, most developers in the Java community see # as a natural future expansion to support static-binding to methods: Method m = #myMethod; The precedence is already set using javadoc (#method). Can't a different symbol be found? Paul From rssh at gradsoft.com.ua Mon Aug 31 03:51:32 2009 From: rssh at gradsoft.com.ua (Ruslan Shevchenko) Date: Mon, 31 Aug 2009 13:51:32 +0300 (EEST) Subject: The Final Five (or so) In-Reply-To: References: Message-ID: <6734a4396e42353d75f83b8bdb566720.squirrel@wmail.gradsoft.ua> > I am hoping the "JSR-292 language support" does not include the # syntax. > I > think that's a very poor syntax since, I believe, most developers in the > Java community see # as a natural future expansion to support > static-binding > to methods: > > Method m = #myMethod; > > The precedence is already set using javadoc (#method). Can't a different > symbol be found? > > Paul > also note, that nothing prohibit from using '#' in both meanings in future. (because starting sequence for row method name is #", not #); static-binding to methods with #" names will start with two # symbols in such case. Method m1 = #myMethod; Method m2 = ##"operator:+="; //Of course, level of ugliness is question of personal taste. >