jastrachan | 15 Jun 10:22 2004

Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?

On 14 Jun 2004, at 20:01, Mark C. Chu-Carroll wrote:
> On Jun 14, 2004, at 8:36 AM, jastrachan@... wrote:
>> Just stepping back for a moment and looking down from 30,000 ft.
>> The invokeMethod() mechanism was a simple hook to allow folks to 
>> intercept dynamic method invocations and do clever things. It was 
>> only ever intended for use by the Groovy runtime when doing dynamic 
>> method dispatch. e.g. if you write a Groovy bean and turn it into 
>> bytecode and pass it to some Java code, the Java code typically will 
>> not see any of the cleverness thats done in the invokeMethod() call.
>> e.g. if we did this in Groovy
>> class Foo {
>>     doSomething() {
>> 	println "Hello"
>>     }
>>     invokeMethod(String name, Object[] args) {
>> 	if (name == "doSomething") {
>> 	    println "Clever Stuff"
>> 	}
>> 	else {
>> 	    metaClass.invokeMethod(this, name, args)
>> 	}
>>     }
>> }
>> Then in Groovy
>> x = new Foo()
>> x.doSomething()
>> would print "Clever Stuff"
>> however in Java, calling this method would print "Hello"
>> So following the principle of least surprise, if we do static method 
>> dispatch in Groovy, shouldn't it work just like Java? i.e. if I did 
>> this in Groovy...
>> Foo x = new Foo()
>> x.doSomething()
>> would print "Hello"
>> I really like the idea of using static method dispatch when folks 
>> want to and getting the performance benefits from that. I'm wondering 
>> if we should support invokeMethod() as an interceptor; it seems to me 
>> that if folks really wanna do method interception which works at the 
>> binary / bytecode level (and so works in Java code and when doing 
>> static method dispatch) that we need to do bytecode weaving instead 
>> (overloading methods & calling pre/post code blocks etc).
> I don't particularly care whether we support invokeMethod or something 
> more like aspect weaving - I really don't have a strong opinion either 
> way. But I *really* hate the idea that adding a type declaration to my 
> code can affect not just its performance, but its semantics.


The invokeMethod() & getProperty() & setProperty() methods were 
originally added to GroovyObject as a simple way for Java code to 
interact with any Groovy object - and as a simple optimisation for the 
generated bytecode. The fact that they provide a kinda 'interceptor 
hook' came as a secondary benefit. I wonder if we should maybe revisit 
the 'interceptor' mechanism, to maybe do things more like AOP tools.

> If we support invokeMethod, then I'd rather go the route that I've 
> been working on: providing a way that static binds will call a bypass 
> method that invokes invokeMethod; that way, even when Java calls 
> groovy, the invokeMethod semantics will be upheld.


I wonder if there's a way for us to only have to do this special 
processing, if someone has really overloaded invokeMethod() to do 
something wacky. e.g. if the compiler adds an invokeMethod() 
implementation (which is harmless & can be ignored) then we could maybe 
mark the class in some way to indicate that the invokeMethod() can be 
ignored when using static method dispatch. (Though we'd need to be 
careful to spot someone deriving from a Groovy object and overloading 

At the very least, its only for Groovy objects that we have to do this; 
for regular Java classes that don't implement GroovyObject we can just 
do normal method invocations.