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.


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 ):
def another( a, b, c ):
def a_normal( self ):

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


verbat 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. All the other stuff are there just for backwards, and must go away in py3k.

That is the python way, "only one way to do it".

About Sets..
I'd like to have a clean core withouth almost anything.
I mean, we have regexen in an external module and Complex and Sets builtin?
Do you more often do math involving complex numbers or text processing?

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) ?

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 :)