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