The key is to remember that, in JavaScript, you aren't really "defining instance methods" in the way you are in almost any other language. You're just passing anonymous functions as the value tied to some key in a dictionary, which happens to be the prototype of some set of objects. Once you get that into your mind and let it play around for a bit, you realize that you could be getting the anonymous function from anywhere!
From a function-factory, that takes some arguments and returns a function:
render: renderWithTemplate("some_template")
From an anonymous function wrapped in something that controls its execution: onScroll: _.debounce(100, function(){ /* do something */ })
Or even by delegating to another object: viewInstance.onScroll = _.bind(somethingElse.render, somethingElse);
Thanks for the great post to help bend our minds around these possibilities.> viewInstance.onScroll = somethingElse.render;
This one is a bit dangerous, because as you mention the "methods" are just anonymous functions assigned to objects. If `render` is expecting to be called on a `somethingElse`, this might not work right without being bound.
> Our decorators work just like Python method decorators, only we don't need any magic syntax for them because CoffeeScript, like JavaScript, already has this idea that functions can return functions and there's nothing particularly magic about defining a method, it's just an expression that evaluates to a function.
Python also has this idea (called ‘higher-order functions’). The difference is in syntax—function calls require parens in Python, and anonymous functions aren't that well supported. Therefore the need for special syntax construct to make decorator use convenient.
Neither does Python, at definition time. All the difference is in the processing performed by the class constructor (`type`) when the class object is created. Before that, it's a bog-standard function.
> which is what allows you to use first-class functional combinators as decorators.
Which is exactly like Python, the original decorators[0][1] predate the syntactic extension by several versions, the original syntax for applying them was:
def some_method(cls):
pass
some_method = classmethod(some_method)
And you could use the exact same syntax to define non-method functions (though not this decorator, of course, as it doesn't make sense for functions)[0] http://docs.python.org/library/functions.html?highlight=clas...
[1] http://docs.python.org/library/functions.html?highlight=clas...
Python decorators are a hack around the lack of proper lambda ;) Just pass the function: decorate -> … Where "decorate" is a fn
There's no point in having an anonymous function decorator. You'd simply inline it into the body itself right on the spot, anything else would simply be obfuscation for the sake of obfuscation. This only makes sense if you're using a decorator applied elsewhere, at which point all languages require you to have named it, so there's no point complaining about lack of anonymous functions here.
Python has first-class functions. It even has first-class methods, with automatic instance binding. It just doesn't quite work how very functionally-oriented people want it to work. Part of the reason I don't like the kvetching that such people do is that it does seem to convince people that Python is lacking function references. Nope. It just doesn't spell them to everybody's taste (for instance, "it doesn't have Ruby blocks" translates to "it doesn't have block syntax", not "it can't do function references", and this is a taste issue not a fundamental capability issue), and the can rarely have moderately inconvenient scope rules if you want to write to outer scopes.
Decorators are syntax sugar, not a new feature.
https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Fi...
What I was speaking to is the desire to write:
class SomeExampleModel:
def setHeavyweightProperty:
triggers('cache:dirty')(
lambda self, property, value:
...something...
My understanding is that Python doesn't like two different things about this. First, the multi-line anonymous lambda being used as the target of the decorator. Second, a function being called with another function as its argument as an expression within an instance method definition.I'm open to reëducation.
ifAuthorized("admin", lambda x:
// more code here