Happy New Year All!

As one of my New Year's resolutions, I'm going to try and implement a 
programming
construct that I've been want to play with for a while - and I think a Groovy 
AST just
might let me do it.

While the syntax part of this is straightforward (I think), I'm not as clear on 
the
how of the method resolution logic that will be at the core.

The basic idea is that I'll be able to designate a section of code where binary
operators would be resolved not against the neighbouring object's class, but 
against
the surrounding context.  Perhaps some code will make my goal clearer....

My understanding of Groovy (and OO in general) is that an expression like
    obj1 + obj2
is interpreted as if it were written
    obj1.plus( obj2)

What I'd like to do is have something like
    withCtx( ctx1) {
        obj1 + obj2
    }
get interpreted as
    ctx1.plus( obj1, obj2)


If I squint at this, it kind of sort of looks to me a bit like how the "with" 
construct
in Groovy works.  But, the with construct is an enhancement to the existing OO
method resolution; this construct would go in a different direction.

(Actually, to be useful, the interior expression would probably be something
like -- var1 = obj1 + obj2 -- but I want to focus on one step/method at a time.)

With this idea, methods between objects (e.g. binary methods) don't belong to 
the
class of (one of the) objects involved, but to the context within which the 
objects
are being used.

And, just to make things more challenging, I'd like to be able to nest and 
compose
contexts.

Consider
    withCtx( Ctx1) {
        withCtx( ctx2, ctx3) {
            obj1 + obj2
        }
    }

Here, the methods of ctx2 would be checked to see if there's a "plus" that can 
take
arguments obj1 and obj2.  If not, then ctx3's methods will be check.  If 
there's no
appropriate "plus" in ctx3, then Ctx1's methods will be checked.

Finally, if there are no appropriate context methods for "plus-ing" these two
objects, then method resolution would fall back to the normal Groovy approach.

To add yet another wrinkle, I'd like to be able to use either a Context class 
or a context
instance when doing this.  So, in the above, if "Ctx1" is a class name (note 
the cap C),
its static methods would be used.  But, assuming ctx2 and ctx3 are context 
instances
(note the lower case c's), the appropriate instance methods would be used.

Hopefully this description makes my goal clearer.

My questions for you are,

    - is an AST the way to go?

    - I'm guessing that I can do the context nesting and composing by building 
on
      methodMissing (with ctx2 chaining to ctx3 chaining to Ctx1 above), but is 
there
      a better way?

    - what might I be breaking in Groovy by doing this?

    - what help/hints can I get from the compiler vs. doing this all at runtime?


Thanks for your time,

Ed Clark

Reply via email to