jastrachan | 25 Jan 12:45 2005

Re: [groovy-dev] Pragmatic Groovy Development and Project Management

On 25 Jan 2005, at 11:22, John Wilson wrote:
> On 25 Jan 2005, at 10:47, jastrachan@... wrote:
>>> I certainly believe that New Groovy is a significantly different 
>>> (and worse) language than Old Groovy
>>> As I understand things (and there is so little information available 
>>> I could be mistaken here)
>>> 1/ The delegate mechanism is being removed from Closure. This means 
>>> that the current Builder mechanism, Expando, GStringTemplateEngine 
>>> and XML-RPC will stop working.
>> The delegate on closures was a complete hack to create builders and 
>> leads to complete dynamic scope of variables. We need to fix this & 
>> put static scoping in place; so at compile time we know where a name 
>> is meant to come from (the outer class, the builder etc)
>> You can still implement your own delegate mechanism on a closure if 
>> you wish & we will put in place a builder mechanism in its place.
> The only thing I have seen which purports to replace the delegate is 
> the with clause which does no such thing.

We've not yet proposed a replacement builder mechanism - though we 
briefly discussed at the meeting a few possible alternatives.

> The delegate does not lead to complete dynamic scope at all. The 
> delegate only comes into play if the static scope resolution fails to 
> resolve the name.
>  You can always tell at compile time if the object is a static or 
> dynamic reference. The dynamic references can either be against the 
> owner (if the owner is a script or declared in a script, if it is 
> another closure or if it is a class which implements get/set Property) 
> or against the delegate. Removing the delegate still gives you dynamic 
> name resolution if the owner is dynamic. So removing the delegate does 
> not decrease the complexity of name resolution within closures to any 
> appreciable degree.

A hack is still a hack, even if its useful :)

Like I said, we will have a builder mechanism that allows you to do 
builder type stuff.

>>> 2/ The introduction of optional parentheses for methods taking no 
>>> parameters makes it impossible for the compiler to distinguish 
>>> between a method invocation and a property access on a untyped 
>>> value. This seems to me to require a complete rethink of how GPath 
>>> works.
>> We need to clarify this. The tests in the TCK right now assume that 
>> parens are required to disambiguate between a property and a method. 
>> i.e.
>> collection.size
>> would work, but if you had a size() method and a size property, you'd 
>> have to use
>> collection.size()
>> to explicitly use the method
> Yes but when you have untyped variables or dynamic behaviour the 
> compiler can't tell what collection.size is. So we have a semantic 
> difference in the interpretation of x.size depending on whether x is 
> typed or not.

No - its nothing to do with typed/untyped. Whatever the type of 
collection, the expression has the same AST & will use the same 
resolution mechanism. But I think size() has to have a different AST to 
size to allow disambiguation between bean properties and methods with 
zero args. We should discuss this on the JSR list - there's a test in 
the TCK for this, we might wanna refine the semantics though

>>> 3/ Various Perl like variable decorators are being introduced in an 
>>> attempt to disambiguate cases introduced by the language changes.
>> Huh?
> Use of  <at>  as a operator/decorator (

We're adding support for annotations via  <at>  to be inline with Java 5 - 
we're also allowing explicit references to attributes (fields) via  <at> foo 
- though most people won't need this as most people will be using bean 
properties etc. FWIW this comes from Ruby, but I'm sure there's 
something like it in Perl as they tend to use all possible operators :)

> and the horrid use of * as an array expander)

* is used in python and ruby (and quite a few languages) to allow lists 
and parameter values to be used together.

def foo(a, b, c) {

list = [1, 2]

foo(*list, 3)

Its unfortunate you find this horrible; its very handy. Also note Java 
5 has the converse end of the relationship, allowing a single parameter 
to be a list of arguments via "...". It just Java 5 doesn't allow the 
converse - to expand an array/list to be the arguments of a method 

>>> 4/ Various breaking changes are being introduced in the way dynamic 
>>> method dispatch is applied to typed variables.
>> AFAIK I've always said that method dispatch should work the same 
>> whether static or dynamic typing is used - the only real difference 
>> is (i) the compiler can warn of typeos on methods and (ii) the 
>> implementation could use the static typing to generate better more 
>> efficient bytecode
> There are logical problems with this approach - you in general only 
> know that you are dealing with some superclass there is always the 
> possibility that the object implements dynamic behaviour even though 
> the superclass doesn't implement a custom invokeMethod (or even 
> implement GroovyObject). So, in general, you can't warn of typos nor 
> can you do static dispatch. The only times you can do this is if the 
> class is final or you have seen the new operation and you are certain 
> that the variable always contains the result of the new. The various 
> discussions I have read on the mailing list leads me to believe that 
> the final implementation will not restrict itself to these cases.

I don't follow.

>>> In addition a breaking change has already been made to the way 
>>> dynamic method dispatch is applied to untyped variables (e.g. 
>>> toString cannot now be processed by invokemathod())
>> What was this change?
> http://jira.codehaus.org/browse/GROOVY-677
> You will note that this issue was opened and closed in a single day 
> and there was no discussion whatsoever of the wisdom of this change on 
> any of the Groovy mailing lists.

We need to support static compile time errors. Groovy Classic has some 
broken stuff in there in this area. I'm confident we can fix it. 
However in the mean time we're gonna have to change a little some of 
the hooks that folks like yourself have used (which were only ever 
introduced into Groovy to help the implementation) and provide a more 
explicit way for you to do the wacky dynamic proxy/dispatch stuff you 
wanna do. Believe me, I've always tried to keep things backwards 
compatible where possible, but the closure delegate & current use of 
invokeMethod() overloading to add dynamic behaviour will have to 
change. I'm sure we'll be include the same kinda stuff you wanna do - 
it'll just differ a little & rather than being a hack in the 
implementation, we'll layer it neatly on a solid base which allows both 
static compile errors and dynamic method dispatch.