Wednesday 14 April 2010

Extension Methods aka Methodize

Thought lately I've been a happy jQuery user, Prototype.js is the first "2.0" javascript library that I used, and I like to keep an eye on what the fantastic team of developers behind it are up to.
Far beyond the Ajax, Dom, Events... features, what is really interesting to me from prototype.js is all the "language extension" stuff. What I mean with this are methods like Class.create, Object.extend, Function.bind... that take advantage of the incredible dynamism of javascript to shape it into a different beast (this said, I'd like to note that I very much appreciate the prototype-based paradigm and I don't ever feel the need to simulate the class-based paradigm in javascript).

One method that called my attention today is Function.methodize. At first it seemed a bit strange to me.
Function.bind seems like an indispensable addition that all of us had wished before it got implemented, Function.curry (I think Function.partial should be a better name, but the currying vs partial debate [1], [2] is a bit confusing to me) sounds familiar from other "functional friendly" languages...
So, what about this Function.methodize?
Well, the sample makes it clear. You have a function that expects x elements and would like to be able to paste it to an object and call it via that object (in a "method invocation style") with that object acting as the first argument.

Note here that the need for methodize comes from how "this" works in javascript. The "this" concept in javascript is more in line with languages like C# or java than with languages like python. In these languages "this" is a special item, the object through which the method was called, it seems rather reasonable for static languages. In python we don't have the "this" idea (the usage of "self" in methods is just a convention), at first it would seem like there's not a so clear distinction between functions and methods, you just declare functions, if declared at the module level, they expect you to type the first parameter in the invocation, when defined at the class level, the first parameter is passed by the runtime using the "invokator object" (well, all this is rather more complex, in fact in python we have function objects, method objects, bound and unbound, Descriptors magic... and it's a long time that I don't touch python).
Anyway, for a so "open" language like javascript maybe the python approach would have been better.

If you think it a bit more, you realize that methodize is just the same as C#'s Extension methods. You've got a static method and would like to call it via an object that will work as the first parameter...
Also in C# this gives us unprecedented extensibility, adding Traits to the game (the article says Mixins, but I think to remember having read somewhere that Mixins can have state and Traits can't... so in that case it should say Traits).
It's interesting to see how some simple compiler magic (if not in the class, just search the method in the list of extension methods with that class marked as this) can add much power to a language.

No comments:

Post a Comment