All 2 entries tagged Macros

No other Warwick Blogs use the tag Macros on entries | View entries tagged Macros at Technorati | There are no images tagged Macros on this blog

March 02, 2007

Multiple Interface Implementation via Proxy

Nemerle is like C# in that it only has single implementation inheritance and multiple interface inheritance. However when modelling business problems it would be beneficial to have multiple implementation inheritance to allow for better code reuse and modularisation.
For example, consider a PurchaseOrder object. We would like to add rich UI data binding functionality and undo/redo operations to it. The .NET framework contains a number of interfaces that should be implemented to achieve these goals. IEditableObject has methods BeginEdit, EndEdit and CancelEdit. INotifyPropertyChanged has an event PropertyChanged. The implementation of these is fairly standard so we do not want to write it in each class. In C#, we would usually make some kind of abstract base class that implements the interfaces and then inherit our real business classes from that.
Whilst this approach is fine for simple object models, things get a lot more difficult when not all business classes require all interfaces. Maybe some are read-only; maybe others have special auditing requirements. We end up creating many strange abstract base classes that implement different subsets of functionality. This inevitably leads to repeated code and a maintenance nightmare.
If we step back, we realise that we are actually abusing inheritance as an attempt to reduce code repetition. A better approach would be to have implementations of single interfaces as single classes that are then pulled together by the actual business classes. The business classes are then in charge of what implementations they require, rather than relying on a rather fragile base class.
The following Nemerle code demonstrates how this might work:

class PurchaseOrder : IEditableObject
    private _editableObject : IEditableObject
    public this()
        _editableObject = EditableObjectImplementation(this)
    public BeginEdit() : void
        _editableObject.BeginEdit()
    public EndEdit() : void
        _editableObject.EndEdit()
    public CancelEdit() : void
        _editableObject.CancelEdit()

The constructor creates and instance of some implementation class. Any calls to the interfaces methods are forwarded to the implementation class. Note that we provide the implementation class with the object that is using it. This allows the implementation class to do things like reflection to get all the private state to be saved.
Basically, we are implementing a form of the Proxy design pattern.
The above idea will work fine (even in C# and VB.NET), however it requires lots of “glue” code to be written. This is where Nemerle macros come in handy!
Imagine being able to write something like:

class PurchaseOrder \
    use EditableObjectImplemenation for IEditableObject \
    use NotifyPropChangedImpl for INotifyPropertyChanged
{
// Look! No glue code at all now!
}

The “use” macro would expand out to code that includes private instance fields and the glue code that calls those instances.
Of course, the macros have to be quite smart, but there are already working Proxy macros for Nemerle that just need enhancing to support events (they already do properties and methods I believe).
Other enhancements allow an implementation class to place demands on the class using it. An implementation of some interface ICircle could provide members like “Area”, “Circumference” and “Diameter” but require the using class to have a member “Radius”. The implementation class calls back into the using class to get Radius. It can then provide the various additional members using that value. This idea follows from the work done on Traits in OOP, the difference here is that implementation are not mixed into the using class at compile time. By keeping them outside, they can do useful things like have their own state.

The benefits of such infrastructure are:
  • Classes are more logically decomposed.
  • Classes are less fragile.
  • Maintenance is easier.
  • Testing business classes by providing stub implementation is easy.

August 04, 2006

Runtime code generation, with macro ease

.NET 2.0 has some very cool stuff in System.Reflection.Emit, namely the DynamicMethod class. DynamicMethod will let you create a new method at runtime that lives inside your current assembly. The only hitch is that you have to create the method using IL – not a high level language like C#/VB/Boo/etc.

My thought for today is: Can we use the syntactic macro abilities of .NET languages like Boo and Nemerle to create dynamic method code whilst remaining in the source language.

For example (psuedo–Nemerle):

myMethod = dynamic( Console.WriteLine("Hello, World") );
myMethod() // Call the dynamically generated method

At compile time this would take the AST passed to the "dynamic" macro, call out to the Nemerle compiler and retrieve the IL. This IL is then used to create a sequence of Emit*() calls needed to create the dynamic method. Finally the macro creates a delegate that can be used to call the method.

Whilst that may seem rather complex, once working it totally removes the need to drop to IL to generate dynamic methods at runtime. I've not had time to think through the implementation details of this. For now I'm just throwing the idea out there – If someone wants have a go, please feel free! The main sticking point is really working out an escaping system to allow interpolation of real code and IL emits. This can probably be done using a second macro "normal" that switches back to normal code.

There is something rather magic about using compile–time macros to generate code for runtime methods. It feels like both sides of meta–programming sync up so nicely, adding a whole new dimension to "code that writes code"! :)


Google Ads

Search this blog

Most recent comments

  • I scratched my eye while i was holding some kind of plastic packaging.. Anyways the corner of the pl… by Ercan on this entry
  • About a year ago my contacts that i was wearing, i guess were fautly, because shortly after they wer… by Jon on this entry
  • I got shower gel in my eye 4 and a half days ago, and becasue i rubbed my eyes a lot, i have scratch… by Chris on this entry
  • This website may help http://www.webmd.com/eye–health/tc/Eye–Injuries–Home–Treatment by S on this entry
  • I somehow got dirt, or debris in my eye. The terrible pain sent me in a tailspin. I was afraid of sa… by Bobbi on this entry

Tags

October 2017

Mo Tu We Th Fr Sa Su
Sep |  Today  |
                  1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31               

Galleries

Blog archive

Loading…
RSS2.0 Atom
Not signed in
Sign in

Powered by BlogBuilder
© MMXVII