jastrachan | 10 Jan 09:07 2005

Re: [groovy-dev] RFE javadoc like reflection syntax

On 9 Jan 2005, at 19:30, John Wilson wrote:

> On 9 Jan 2005, at 18:30, Jochen Theodorou wrote:
>> Currently we have a problem in Groovy:
>> class Foo1 {
>>   void h(){}
>> }
>> f = new Foo1()
>> c = f.h
>> println c
>> you will see c is a closure - but:

Yes - I think this is confusing - we agreed this at the JCP meeting - 
that to get a closure for some method of a certain name, we should add 
some new helper method. So when we make this change, f.h would do as 
you suspect - or throw an exception saying no such property/method.

To get a closure to the method, we'd need to do something like


or whatever we call the new helper method

>> class Foo2 {
>>   String h = "h"
>>   void h(){}
>> }
>> f = new Foo2()
>> c = f.h
>> println c
>> you will see c is "h" and no closure. Using my syntax we could write 
>> c=f#h() to get a method object and be sure we don't get the field 
>> value and not the field. using c=f#h(...) could do the same as the 
>> f.h in the Foo1 example and f#h could get the field object not the 
>> value.
> Yes these are problems with the existing language. I believe that the 
> intention is to allow functions to be called without supplying empty 
> parentheses. This means that we have four different interpretations of 
> f.h.


> Class Foo {
> 	int h = 1
> 	int getH() { return 100}
> 	int h() { return 200}
> 	String h(String s) {return s}
> }
> f = new Foo()
> println f.h
> 1/ print 1
> 2/ call getH() and print 100
> 3/ call h() and print 200
> 4/ generate a closure which does dynamic dispatch to chose which of 
> the h functions to call when it is called. Print the result of calling 
> toString on the closure.
> As I understand it one of the the results of the the JSR meeting in 
> London last year was a set of mechanisms which allows all of these 
> cases to be distinguished (using f. <at> h chooses one of them but I'm not 
> at all sure which one)

f. <at> h chooses the field

> Perhaps somebody who was at that meeting could confirm that this is 
> indeed the case and explain how the trick is done.
> If these problems have been fixed then your notation is redundant.

Yes, you're correct. The thing which is not completely clear is which 
should be chosen, the property (getH()) or the method (h). My gut feel 
is that it should always go for the property first, since thats the 
common use case of the normal property syntax. foo.h is by default a 
property accessor and it would only use h() if there was no property.

>> There is another problem:
>> class Foo3{
>>   String methods=null
>>   String fields=null
>> }
>> now you can't use f.methods to get a Collection of methods or 
>> f.fields to get a collection of fields. with my sytax this would be 
>> f#.fields and f#.methods because f# returns the class of f. This way 
>> you have it the same way as using the class Foo3# will return Foo3, 
>> so Foo3#.methods will return the same as Foo3.methods without the 
>> possible problem of having a static field inside Foo3 named methods.
>> Another way would be to remove these things, but then.. how much of a 
>> first class object is a class?
> If the new language spec does fix the problems we have covered above 
> they cover this case too.
> I would suggest that you ask on the JSR mailing list for clarification 
> as to how these cases are distinguished. I wish you more luck in 
> getting replies that I have had.

Well firstly, foo.methods in the new language would still work as 
expected - as the 2 fields are private by default; you need to add the 
keyword 'property' to make them public bean properties.

To access the underlying methods/fields if you have a naming clash, you 
can always get them from the MetaClass. Otherwise, if you overload some 
methods with something else, what do you expect :)

So if you do decide to overload 'methods'; you can do