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