07/10/2011

Implement Python decorators in CoffeeScript

After wondering about expressive coffeescript support for metaprogramming, we've found with @fredZen some pattern for simulating some features like decorators, as found in Python
What is a decorator in python : simply a wrapper for a function, (a function which takes a function as parameter and returns a function, no wizardry here, coffeescript can do it), so let's write our wrapper :



# wrap is like a python decorator
wrap = (func) ->
    rf = (args...)-> # declare a function to wrap func
        alert "before func"
        func(args...)
    rf.wrapped = true # Tag our wrapped function (for a later use)
    rf # Returns the wrapped function

So here we have a simple function for wrapping, we can use it in a class like this :

class Toto # class Toto has metaclass 'registered'
    func1: wrap -> # decorator wrap of func1
        alert "hello func1"

# Example run
toto = new Toto() 

toto.func1()
Running this will alert a first message : 'before func' then another alert 'hello func1'.

It's a first step for wrapping function, but we can go further and use the flag by wrapping the class declaration :


# Registered acts as a wrapper for class declatation, it occurs after type construction
registered = (klass) ->
    klassName = klass.toString().match(/function ([^\(]+)/)[1] # Grab name of the class
    for name, f of klass.prototype
       if f.wrapped
          alert klassName + 'has wrapped func ' + name
registered class Toto # wrapping class Toto
    func1: wrap -> # decorator wrap of func1
        alert "hello func1"
    func2: ->
        alert "hello func2"


toto = new Toto()
toto.func1()
toto.func2()
Running this will alert :
  • 'Toto  has wrapped func func1'
  • 'before func'
  • 'hello func1'
  •  'hello func2'
It's some solution to the problem I have in my previous post, but it doesn't solve everything, as the class wrapper is just a wrapper, i'd like to have any extended class from Toto running the wrapping code without specifying the wrapper before class declaration, just like in metaprogramming.

04/10/2011

CoffeeScript, it could be a great story, but...

Oh yeah, CoffeeScript is nice and sexy, it allows to write javascript quickly, but...

It's missing some important features I need for KaraCos implementation.

Context :
KaraCos exposes node objects from a node tree on top of the HTTP protocol.
Some object methods can be accessed from HTTP using a REST API. Each node can expose a WSDL or equivalent.
KaraCos dynamically assign an object type to a Node from one of it's attribute in the content repository.
To achieve such task, i used in Python some metaclass, so i could assing a particular type of 'class' to a déclared class, and then trigger some internal action at class declaration (registering the type as a data-linked type then gives the db wrapper a registry to allow him to choose corresponding class).

This META programming aspect is missing from coffee, let's watch the coffeescript example of class and it's generated part :

Look at how class Animal is converted to js, my need is to add some treatment just before the return Animal statement. From the example of python, metaclass allows as well to wrap class constructor with some generic function.

Today there is no way for a CoffeeScript programmer to achieve metaprogramming. I'm right now studying the coffee anotated source to find how i could extend it a bit, but this is my first compiler experience. Hopefully, @FredZen gives me some help, are there any other volunteer for such a challenge ?

CoffeeScript will then look much more appropriate (and flexible), don't you think ?