jastrachan | 26 Jan 11:12 2005

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

On 25 Jan 2005, at 14:59, John Wilson wrote:
> On 25 Jan 2005, at 13:19, jastrachan@... wrote:
>> The delegate is a horrible hack to do builders which leads to all 
>> sorts of naming issues & complex runtime name chasing in many 
>> different scopes (is a name a global function, a method on the 
>> parent, or on this new magic delegate thingy etc).
> Continually repeating this doesn't make it true, I'm afraid.

Its a fact - I put the delegate in the Closure purely to implement 
markup - it does not belong in the design of a closure, nor do most 
users of closures have any need for such a thing.

A block/closure is meant to be bound to its lexical scope. Period. 
Being able to magically switch its scope to some completely different 
object (the 'delegate') is completely bizarre, leads to confusion, name 
resolution complexity (having 2 object hierarchies and the global stuff 
to hunt along to find a name) and has no prior art - languages like 
smalltalk & ruby have no concept of 'delegate' it does not in any way 
belong to the concept/design of closures. We're trying to simplify 
Groovy and remove some of its strange, rough, complex edges and I think 
the 'delegate' is certainly one of them.

>  The delegate is the 'name resolver of last resort'.

Let me say this then - can you describe the use cases of why you need 
the 'invisible delegate' object in a closure. As I think by using 
regular closures and parameters & currying, we can pretty much achieve 
what you want. If through this discussion we find its really required, 
we could consider keeping it..

i.e. can we spring clean closures, make them simple again and then 
support something like the delegate stuff you wanna do?

>  So it only gets involved when all other attempts to resolve the name 
> has failed. So the rules for name resolution in a closure are very 
> simple.
> 1/ If the name is local to the closure (the variables "owner" or 
> "delegate", a parameter name (or "it" if no parameters) or a local 
> variable) then use that.
> 2/ If the closure is in a method and the name is a local variable or a 
> parameter of the method then use that
> 3/ If the name can be resolved against the owner then use that
> 4/ If the delegate is not null and the name can be resolved against 
> the delegate then use that
> 5/ If all the previous attempts fails then the name cannot be resolved
> This mechanism works for closures in scripts, closures in methods on 
> classes and closures in closures.
> Note that steps 1 & 2 can always be performed at compile time. Step 3 
> can sometimes be performed at compile time.
> When step 3 can be performed at compile time the compiler can generate 
> the delegate resolution code inline.
> I really don't see where the claimed naming issues and complex runtime 
> name chasing comes from.

I've repeatedly explained why delegate came into being, why its a hack, 
why closures are meant to be simple objects bound to their lexical 
scope (and there's no prior art of people randomly binding a closure to 
some completely different lexical scope). Sure we could come up with 
some rules for their use, like above, however before spending time on 
complex rules to decide how to resolve a name inside a closure - I'd 
like us to first capture what it is you're trying to do - as it could 
be that either

(i) there are other ways to solve the problem rather than tying the 
'delegate' feature to closures per se (e.g. using bound variables or 

(ii) the problem is not necessarily connected with closures, its more 
to do with general proxying/delegating/indirection or something.

So far the only use case I've heard for keeping the delegate is that we 
use it for builders; and I've already said, we need to overhaul the 
builder stuff as its just too complex & wacky right now (is a name on 
the builder, on the owner class, a variable in lexical scope, a global 

Maybe John, you'd be happier if we postponed talk of the delegate being 
removed until there was a suitable builder proposal on the table? (I 
was hoping to get the core language sorted first, then do builder stuff 
once we've a solid foundation, but we could spin it off in parallel if 
you like?)