Proposal for Property Accessors

Noctarius me at noctarius.com
Sun Jan 6 04:40:42 PST 2013


Am 06.01.2013 11:22, schrieb Jochen Theodorou:
> To drive the language list down there further I name the Groovy 
> variant... fully aware that it is not likely something for Java at all. 
> In Groovy we do:
> 
> class Egg {
>    int color
> }
> 
> This will generate a getColor and a setColor method, just like you 
> expect from the Java Bean Spec. You can still write those methods, if 
> you want, then the method is taken instead of the generated version
> 
> In code you can access the property like this: egg.color
> 
> so exactly the same as a field. And that is actually a problem, since 
> you now have to make a difference between a field and a property. 
> Because sometimes you don't want to call the getter or setter, sometimes 
> you want to write directly into the field, since getter or setter may 
> contain additional code. If you would not need additional code, you 
> could simply go with fields.
> 

In that case I would suggest to write a special method not routing
through the getter/setter since those would only be used externally
(not internally in the defining class).
In (I guess) 99% of all cases you want the getters / setters to be
called.

> If you go the route with user getter/setter and generated getter/setter 
> at the same time, you get problems with knowing when you need what. 
> Another problem are indexed properties. It is no problem in Groovy to 
> have a property return a field, but getter/setter with the index as 
> parameter look in Groovy like method calls. So they would either need 
> another syntax or they are not supported... which is what Groovy does in 
> the end. You can still call them as methods, but if you want to do 
> egg.color[1], you need a color property returning an array.
> 

For indexed fields I thought about (for one-dimensional arrays) to be:

property int[] foo {
  (index, value) -> { foo[index] = value; }
  (index) -> { foo[index]; }
}

For multi-dimensional arrays it's not so handy and I stuck at what a
nice syntax would look like but maybe something like this:

property int[][][] foo {
  (indexes, value) -> {  // indexes itself is an array length
                         //of given indexes
    ...
  }
}

But as I said, currently not sure what a nice syntax would be, maybe
in that case there is no nice way - not sure.

> As for a special bytecode instruction... normally invokedynamic is 
> powerfull enough to resolve such things on the bytecode level. I see the 
> problem much more on the syntax side.
> 
> Recognizing what a property is from existing Java code is also an issue. 
> Thanks to our approach, if there are getter/setter, then they are 
> properties. A compiler then can for example simply call the getter and 
> setter like a normal method... really no special need for a special 
> instruction just for a static compiler. At least that is what the Groovy 
> static compiler is doing.
> 
> bye Jochen
> 
> Am 06.01.2013 10:43, schrieb Noctarius:
> [...]
>>>>>>> but, how about the syntax: public int get color() { return
>>>>>>> iColor; } public void set color(int value) { iColor=value; }
>>>>>>> public int get[](int idx) { return array[idx]; } public void
>>>>>>> set[](int idx, int value) { array[idx]=value; }
>>>>>>>
>>>>>> The idea about the proposed syntax was to be minimalistic, it
>>>>>> should prevent you from writing getters and setters which are just
>>>>>> a big bunch of boilerplate codebase.
> [...]
>>>> Here's the C# approach:
>>>> public class Egg {
>>>>     private int color;
>>>>
>>>>     public int color {
>>>>       get
>>>>       {
>>>>         return this.color;
>>>>       }
>>>>       set
>>>>       {
>>>>         this.color = value;
>>>>       }
>>>>     }
>>>> }
>>>
>>> yes, and with an AS3-like approach:
>>> public function get color():int { return this.color; }
>>> public function set color(value:int):void { this.color=value; }
>>>
>>
>> The problem is, I see no clear standard what makes sense to say
>> "yeah let's gonna go that way".
>>
>> AS3:
>> public function get color():int { ... }
>> public function set color(value:int):void { ... }
>>
>> C#:
>> private int color;
>> public int color {
>>    get {
>>      ...
>>    }
>>    set {
>>      ...
>>    }
>> }
>>
>> Ruby:
>> attr_accessor :color
>>
>> C++:
>> Well no real kind of property but could be emulated using operator
>> overloading
>>
>> MS C++:
>> __declspec(property(get = getprop, put = putprop)) int the_prop;
>>
>> D:
>> private int m_color;
>> @property public int color() { ... }
>> @property public int color(int value) { ... }
>>
>> Delphi had some way but I don't remeber it (thanks to god I finally
>> forgot about Delphi).
>>
>> JS:
>> color: {
>>    get: function() { ... },
>>    set: function(value) { ... }
>> }
>>
>> Objective-C:
>> @property int *color;
>> @synthesize color;
>>
>> PHP:
>> function __get($property) { ... }
>> function __set($property, $value) { ... }
>>
>> I guess there are a lot more kinds of properties syntax out there
>> and it neither seem to have a clean standard and nor that anyone of
>> the above examples is better then the other. The interesting fact
>> is, that AS and JS are totally different even though both are ECMA
>> Script derived. JS in this case is more similar to C# (or other way
>> round ;-)).
>>
>>> now, if one takes the above, and converts it to Java-like declarations,
>>> one gets:
>>> public int get color() { return this.color; }
>>> public void set color(int value) { this.color=value; }
>>>
>>> more-or-less...
>>>
>>>
>>> at least in my language, getters/setters are internally mostly just
>>> normal methods, so the above would internally become something more like:
>>> public int _get_color() { return this.color; }
>>> public void _set_color(int value) { this.color=value; }
>>>
>>> with index properties having names like "_getindex_" and "_setindex_".
>>>
>>> actually, more-so, they are currently handled as a parser-hack.
>>>
>>>
>>> the other part of the process is basically just handling getting/setting
>>> them differently.
>>> the closest direct JVM analogue of the mechanism would probably be the
>>> "invokevirtual" instruction.
>>>
>>> granted, in my VM, these are implemented as a special case of the field
>>> load/store instructions, which more work by detecting the presence of
>>> the getter/setter method, and using special logic to call these methods
>>> instead.
>>>
>>> this would be analogous in the JVM to detecting and handling this
>>> special-case in the JIT.
>>>
>>>
>>> the major functional difference being in my case that my VM uses
>>> threaded-code (execution as a sequence of calls into C functions) as a
>>> kind of cheaper/lazier/slower alternative to a JIT, with this
>>> translation taking place the first time a given method is called (in my
>>> VM, it is effectively "frozen" after this point). (side note: while
>>> threaded-code is somewhat slower than JIT compiled code, it has the
>>> advantage that it is easier to implement and maintain, as it avoids much
>>> of the hairy compiler logic and piles of target-specific ASM code...).
>>> (though, it is also possible to mix natively generated code and calls
>>> back into VM functions, but either way...).
>>>
>>>
>>> or such...
>>>
>>> _______________________________________________
>>> mlvm-dev mailing list
>>> mlvm-dev at openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>>
>>
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>
> 
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
> 



More information about the mlvm-dev mailing list