In OILexer, when you define a rule as an alternation of other rules, such as:
A ::=> /* The '>' represents a point of collapse. */ B | C | D ;
I was working on OILexer's code gen process and I've always been a little miffed by the level of deep diving into object graphs that I've had to do for left-recursive representations of mathematical operator precedence (maths, * before + and so on)
Sometimes to see that they typed 5, I would have to go n levels deep, where n is the number of precedences defined in the language.
Instead of making a type that represents 'A' and giving it a single child of either a B, C or D, the logical solution was to use inheritance, and if you have a 'D' in place of that 'A', you'd have a derivative of D which is also an A.
This is all well and good, but when you're trying to debug an app, it can create some developer-based bottle necks (time-wise.)
Here's an example of what debugging was like before the automated DebuggerTypeProxy instances:
After automating the debugger type proxies:
You'll quickly notice that getting to the meat of the definition is near immediate by comparison.
The example, in both screenshots, represents the opening concept, just expanded out a bit further.
This does create some nasty object hierarchies but the trade-off of generated types for the simplicity of browsing the object hierarchy makes it worth it in the end.