A Late Entry
Neal Gafter
neal at gafter.com
Sun Aug 9 11:22:29 PDT 2009
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 <gzoller at hotmail.com> 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
>
>
More information about the coin-dev
mailing list