Proposed improved decorator syntax

John Roth newsgroups at jhrothjr.com
Fri Aug 6 14:37:02 CEST 2004


"Bruce Eckel" <BruceEckel at MailBlocks.com> wrote in message
news:mailman.1248.1091763229.5135.python-list at python.org...
>
> Thursday, August 5, 2004, 6:54:56 PM, barnesc at engr.orst.edu wrote:
>
> > Recognize that we're *really* trying to create function metadata. A more
> > flexible solution is to make a metadata dictionary be part of function
and
> > class definitions.  Then 'decorator' simply becomes one name among many
> > different metadata names.
>
> I have to say I find this argument compelling. I can't say whether the
> syntax works well, but if the fundamental problem is metadata, then
> solving that in a way that solves all aspects of metadata is
> desireable.

The trouble is that the original issue was not metadata. It was that
a lot of people found the 'classmethod' and 'staticmethod' built-in
functions both ugly and too easy to overlook.

These functions (together with the 'property' built-in) in fact
create new objects (descriptors) and return them; the original object
becomes
an attribute of the new object. In other words, it's somewhat similar
to the decorator design pattern, hence the name.

In these cases, it's not a matter of metadata. I suppose one could
implement class and static methods in terms of metadata, but this
would add another dictionary lookup to an already barouque
function/method call process.

One can also use this facility to insert metadata into the function
object, but again it's simply syntax sugar for an already existing
capability.

> That said, I observe that this seems to be a fairly new topic for
> many, including myself; I have some grasp of Java's metadata facility
> and less of C#'s (although I understand C#'s to be more limiting than
> Java's) and I have not read anything terribly in-depth about either.
> It reminds me of my first exposure to C++ templates many years ago --
> it seemed like there was a lot more to it than meets the eye, but it
> took me years to really start to grasp what it was about (by
> understanding latent typing via python).

There's actually a lot less to metadata than meets the eye. The
basic fact about metadata is that it's data about the program that
makes sense to outside tools that are processing the program.
It may also make sense to routines within the program that
deal with other parts of the program on a meta level - the
typical user of the language's reflection facility.
In other words, you have to know the tool a particular piece
of metadata is directed toward in order to know what it means.

On the other hand, there is a lot to creating a really useful
metadata facility. I may want metadata for more than one
tool in the same program, and I may also want metadata
that is more structured than a simple key:value pair.

I'm not all that familiar with the metadata facilities in either Java
or C#, so I may be wrong by saying that the designers
copped out of dealing with these issues. You can see the
same issue in Python programs when you have various
tools squabbling over who owns the docstrings.

> One thing that has come up in Java is that metadata has been suggested
> for use in implementing a version of aspect-oriented programming,
> another feature I've been struggling to understand. The one thing
> about aspects that has occurred to me is that macros seem to be trying
> to solve a similar problem (changing code behavior across the code
> base), as do metaclasses. Same problem, very different approaches and
> degrees of effectiveness. Things like the implementation of
> 'synchronized' is more aspecty than it is metadata; it is implementing
> behavior changes rather than just attaching information to something
> (the original intent of metadata; in Java you must generally write
> additional code in order to add behavior based on a metadata tag).

When someone wants a facility badly enough, there is a tendency
to abuse other facilities to get it. This is why people seem to
see "metadata" in the decorator proposal, and it's also why people
seem to want to abuse anything in sight to get AOP functionality.

> I suppose the question, then, is this: what is the true intent of
> decorators? Is it for code behavior change, or metadata, or both? If
> it is for code behavior change, how do I hook into that with my own
> code; if I wanted to implement, for example, logging upon entry and
> exit of a method (the classic AOP example) or to begin and end a
> transaction upon entry and exit of a method?

As I said above, the original intent was to provide syntax for
the existing classmethod and staticmethod built-in functions.
In other words it's a behavior change.

There are a number of AOP packages out there. They're all
based on descriptors, at least as far as I know. It would
certainly be possible to re-implement them in terms of this
syntax proposal, but it brings no new functionality to the
table - it's just syntax sugar.

> For that matter, should we limit the syntax of decorators to always
> being at the beginning of a method? True aspects allow you to put a
> cutpoint at any point in a method; perhaps decorators shouldn't be
> restricted (even if we choose not to implement these ideas right
> away).

It depends on what you mean by a decorator. If you're talking
about the function that is invoked by the syntax, think in terms
of the already existing classmethod, staticmethod and property
built-in functions. They are usually invoked when the class is
being created (during import time), and result in a descriptor
being bound to the identifier rather than the original function.
The original function becomes a property of the descriptor.

The descriptor is not invoked at the beginning of a method.
A descriptor is invoked instead of the original method (a
consequence of the descriptor being the object bound to the
identifier rather than the original method). It can then invoke the original
method at any place in its process it finds suitable, including
completely ignoring it (probably a programming error!)

> These issues are tricky but they could be very powerful. And this
> conversation is sounding an awfully lot like some of the language
> design stuff that happened in the C++ committee. Some members decried
> this, saying that the committee should only be codifying existing
> features, but I think it was very necessary for these things to be
> tried, even if they didn't always work out.

It's a lot less tricky than it seems.

> And I think we may be at a point where only experimentation will tell
> us what works and where this thing needs to go. No one has enough
> experience with it -- although some might argue that this is the
> reason we shouldn't put it in at all, I think that it means we need to
> try something out and iterate as we learn.

Descriptors (which is what this is based on) have been around
since release 2.2. All this proposal does is provide syntax for
creating and installing descriptors. There is nothing in this proposal
that could not be accomplished by invoking module level functions
after the original method has been defined.

It is purely syntax sugar, containing a large number of empty calories.

> Bruce Eckel





More information about the Python-list mailing list