JP commented on the @decorator syntax recently checked in to a Python alpha. I agree with him. Moreover, despite the fact that Guido has pronounced such agreement futile, I agree with Jim Fulton and I think that this should be a library issue, not a language issue. (Does anyone think it's peculiar that the authors of two of the most popular chunks of free Python software who have a very limited history of agreeing with each other, agree on disagreeing with Python's designer on language features like this?)
The thing that's most disappointing to me in this is that I had finally come around to accepting the community's rationale against macros: that it was too dangerous to allow arbitrary changes to Python's syntax because it would make the local languages confusing and it would make the resulting language harder to learn and harder to document.
The need for macros doesn't go away, though, and technical necessity becomes distorted by social pressures. I believe that Python could benefit from a lot of different syntax additions, most notably block syntax and continuation syntax, to facilitate programming in the asynchronous model that Twisted uses. I can't add these myself, though, because Python doesn't provide the necessary hooks, and I don't have the patience to agitate on python-dev until my pet feature is added, unlike some people.
I haven't run the numbers, but I imagine that something like one out of every ten thousand methods I write is decorated in some way. Closer to one in five is an asynchronous callback. Why is it that the extra convenience of one-character syntax is necessary for this task which is extremely uncommon? Apparently because other people in completely different application domains find it is more common for them, and those people are more willing to spill gallons of virtual ink complaining about the inconvenience and unreadability of writing "decorate(hello)" vs. "@hello".
I think it is a bigger deal that I have to write ".addCallback(lambda x: doSomething())" rather than "wait; doSomething()", but I don't have the fortitude to convince Guido that "something is better than nothing" in this case. I have been hoping for years that "something" would arrive in the language.
These kind of ad-hoc language modifications strike me as more dangerous than a real, powerful macro system, because they don't just pollute the language for some people, they pollute it for everyone at once because of some people's needs. You have to hack Guido's brain, not the interpreter, to implement your macros, which is both more time-consuming and more detrimental to the community as a whole. Macros increase complexity locally and utility locally; a static language decreases complexity globally and utility globally, but every time someone successfully pushes through a feature like this, they increase complexity globally but utility locally. It's the worst of both worlds.
Of course I'm exaggerating. This feature in particular is not very worrisome, but the trend it indicates is.
The strange thing is that I really don't understand Python's design when things like this get bolted on to the side. Every time I think I've finally got the "pythonic" vibe something weird like this happens. I suppose that's what makes this feature so bad to me. I don't know why I am disagreeing with Guido, because I don't understand the aesthetic he's using to make this decision. From what I can tell just using the language and reading python-dev, it's more or less random.
I hope I'm wrong. I was wrong about the new object model (except __class__ mutation!), and I'm grateful for that every day. Still, even after reading a lot of the ranting, it seems to me that the @decorator syntax is being added because it's easy, not because it's important.
Migration Report
3 days ago
7 comments:
1. staticmethod and classmethod are still, IMO, horrible warts that add complexity without adding expressive power. (I guess maybe you disagree? I'd like to see counterexamples. Guido's argument was apparently, "They are among the most requested features," which is just stupid.)
2. Given that they exist, they are even worse when you have to write them after the function being defined. It's not about @staticmethod foo versus staticmethod(foo). I doubt I can add anything new to the discussion there so I'll leave it at that.
3. I'm disappointed with the @syntax --- I thought [staticmethod] was much better --- but I'm happier with something than nothing.
4. I agree that first-class blocks would be a better addition to the language because they would allow the same syntactic sugar to be written as a library function.
5. I think Guido may be suffering from a second-system effect now, or may have when he worked for Zope Corp.
Where were you wrong about the new object model? Google isn't very good about queries like "What did Glyph Lefkowitz think about new-style classes?"
I'm unhappy about two things.
The @silly syntax is ugly and unpythonic. I would much more prefer block-syntax like "decorator require_int, staticmethod:" where I can put an arbitary number of functions under it.
There's the syntactic reflection of the decorator-pattern. This reflection covers the process of declaring something as decorated. but it does not cover something beeing a decorator. It implicitly assumes that you're following the decorator-pattern, while not enforcing it. imho that's against 'explicit is better then implicit'.
As a mediocre programmer I'm worried about Python's future.
I've programmed Python almost daily for 3years and have not even begun to understand what decorators are good for. New features as Generators, list comprehension has just made me less productive. I can appreciate the compactness and clarity of both but they don't add anything I missed. I've stopped using list comprehension as I often find myself starting writing one and then discover I need something that cant be done with comprehension and have to rewrite as a good old for loop. I've also stopped using generators as generators often just generates bugs for me :-), bugs I did not encounter before.
None of the features are destructive by themselves but as more and more features creep into the language core (Generator expressions) somewhere along the line Python will just end up as a nice language among other nice languages.
That said I'm very much looking forward to new Python releases as the richer library is much appreciated.
How much will decorators affect people like me? Will I have to understand decorators to read common python code? Or will it only be used by a few specialized ObjC developers?
> How much will decorators affect people like me? Will I have
> to understand decorators to read common python code? Or will
> it only be used by a few specialized ObjC developers?
You will probably need to recognize the syntax and the
implications of its use. Whereas generators and list
comprehensions are almost exclusively an implementation
detail you can ignore, decorators often affect a public API.
You may not need to understand how they work, but you'll at
least need to have an idea of what the results of using them
are.
I'm a big fan of generators and rarely I write programms where I don't use a bunch of them, they help me a lot. I use list comprehensions from time to time, and find them usefull. I'm absolutely thrilled about the generator-expressions, because they're not the complement of list comprehensions, they're loop-complement of lambda functions, which are very usefull when dealing with a lot of callbacks.
staticmethod and classmethod allow you to directly provide interfaces from a class and also from its instances more conveniently. I've almost never had to do this, but in the rare cases where I want to it's handy.
I was wrong because I felt the new object model was a waste of time, when features like much-closer-to-proper metaclasses and __slots__ have actually been a huge boon to me. In fact, I believe I was so wrong that my main concern with Python's development at the moment is the hope that old-style classes will be removed in a release soon.
It seems to me that you could already provide interfaces from a factory and the instances it created, just with slightly more work.
My objection to the new object model is mostly that there are two incompatible object models in Python at the moment, and if you accidentally try to use features of one of them on objects of the other, it often fails silently. I think the new object model is probably better than the old one, although I'm still not sure if its complexity justifies it.
I'm also hoping that old-style classes get removed soon, since there isn't a chance that new-style classes will be.
Post a Comment