Function decoration in haXe: Glue

The decorator pattern is a well known method of adding additional functionality to classes at run time. Essentially, programmers often find themselves in a situation where they want to add additional piecemeal functionality to a class without resorting to complex multiple inheritance.
While there’s a variety of methods for accomplishing this with classes (decorators, mixins, etc.), there’s not much in the way of flexible respecification for functions. Recently, I came up with a way of “binding” functions together using HaXe, similar to my signal/slot framework, except that in this case type safety is preserved. I call it the Glue class, and it’s available on google code.
Essentially it works like this:
- Create a dynamic function that you can override. It can be an instance field, or a static field for a class. Give it any sort of type/arity that you want:
public static dynamic function myFunc (x:Int):Void{} - Assign the output of an appropriate Glue method to the function:
myFunc = Glue.join1(myFunc, myOtherFunc);
- In this case, the Glue function “join1()” is joining myOtherFunc to the original myFunc method. As long as myOtherFunc matches the arity of myFunc, this will succeed.
- myFunc() now calls myOtherFunc() as a side-effect. (the return of myOtherFunc is discarded). All the arguments to myFunc are passed to myOtherFunc as well.
The overall effect of this operation is very similar to the decorator pattern for classes. The method is permanently overridden, and extra functionality can be added in a very ad hoc way. This allows for some fairly complex functionality to be driven from a single function call. Something like this might be useful in specialized debugging methods, gui controls, or anywhere that you want to accomplish a varying number of tasks from a single function call. Since it’s a run time change, it’s easy to single out instances that you want to “Glue”, rather than operating at a class level. Finally, since it preserves the type information for both myFunc and myOtherFunc, you can rely on the compiler to catch any mistakes you make in the Glue call, or when you absent-mindedly change either myFunc or myOtherFunc later.
One potential drawback to this is that it is tricky to automatically “undo” such Glued methods. HaXe cannot tell (through Reflection) that a function has been modified, and the closures generated by Glue are “rewrapped” once they’re assigned to another dynamic method, so the Glue class cannot detect if a dynamic method has a “Glued” function. The programmer would have to keep track of this themselves. It’s also necessary to use the appropriate Glue join method… For instance, there is a join1 method, which works with one argument methods, a join2 method, which works with two arguments, and so forth.
The ability to do this sort of strongly-typed method binding is interesting, and fairly unique to haXe (at least in terms of the other languages/platforms it targets). I get the feeling that it’s a tool in search of a purpose at the moment.
You can check out a demo I put together here.




