Tuesday, August 03, 2004

Python 2.4 Decorators

Ok, here's a controversial issue. There's a few changes in python 2.4 that are somewhat hotly discussed.

Most of the features are rather okish I think, what I have a strong opinion about are the following.

Buildin Set Objects
This is a feature I'll love. I think sets are a quite usefull addition to the containers, in facto so usefull that it's legit so I don't have to write "from sets import Set as set" and can write down set literals. I use them a lot and have asked myself since why it hasn't been adopted earlier. Two thumbs up!

Generator Expressions
It is a little strange at first, but I think it's a natural and powerfull complement to list expressions. There's lambdas which enable lisp-like in place functions. There's list comprehensions which can be used in expressions. And now there's generator expressions, which can not only serve as a short form of generator-defintion, but also this expressions can be used in expressions, for example as arguments to a function, written in place. I like it, it will make for some nice and tidy code. That's pythonic, two thumbs up.

Decorators

I've very mixed feelings about this. On the one hand I rarely use function decoration as a pattern. On the other hand there's some rather large and liked frameworks, which do this kind of pattern extensively. I don't actualy know how many people work with this pattern realy, but I'd estimate that it's not the majority of users, perhaps not even near.
So it's a feature only a small group of people will realy benefit. Alone for this fact, I think consideration should be very carefull if it's included or not.
Then there's the story of the syntax. I can see that this a usefull pattern, once you start fiddling with it. I can also see that it's nice if a language supports a pattern. But imho @silly is no way to go. I have to type this sillyness everytime I want to decorate a function. For each decorated function it will be an additional @+funtion-name. And if I want multiple decorators nested, which is a nice idea, I will have to fill a line with multiple @. And this FOR EACH FUNCTION. Holy shit!
If it must be that the language starts to support this kind of pattern ( of what I am not so terribly sure ), then please, with sugger on top, make it easy to read, nice to look at, and in a way that safes you a lot of typing. That would be like... the decorator block. Runs like this.


class someclass:

decorator require_int, staticmethod:
def foobar( a ):
pass
def another( a, b, c ):
pass
def a_normal( self ):
pass


That's a form that I would actualy like, and it give you the power to easely decorate a whole set of methods/functions.

1 comment:

Florian said...

>>I don't look at genexp as a complement. Genexp are
>>what everybody should be using instead of
>>map,filter, imap, ifilter, and list comprehension.

It would be rather hard to replace functions like izip/zip or chain with a single line GenExp. I agree that in some places some of the functions can be replaced by listComprehensions/GenExp, but it's handy to have the functions just in case you're not in one of these situations from time to time.

>>Do you more often do math involving complex numbers
>>or text processing?
Rather often I do text-processing in python.

>>OTOH why do you feel convenient to have a Set (wich
>>you can emulate with a dict) and not have an
>>optimized uniform array (wich you can emulate with
>>list) ?
I think we both agree that set-operations are rather common in computation. Unifying, Intersection, etc. are handy to have in order to spare you to write a few loops more. In fact what convinced me that sets are usefull, I took some code I previously wrote without the use of sets. I replaced all that pescy loops and ended up with much cleaner and smaller code, that was also faster.
Now When I want sets, I want them to be good. But I also like my scripts to be self-contained ( one script, as little dependencies as possible ). As I begun using "from sets import Set as set" anyway, it's good it's buildin. And as a plus I get set-iterals, which is also nice to have. What's not to like :)