473,383 Members | 1,789 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Purely emotional perspective

I have only been using python for a few years, but I have loved it every
step of the way. Each time a new version was released, it contained
improvements that enhanced the readability and feel of simplicity (such as
list comprehensions, substring in string, ...). And each such improvement
delighted me even more, because this is exactly why I loved python in the
first place.

Now come decorators, introducing a non-alphabetic symbol (instead of say, a
new keyword), and worst of all for readability, they come *before* the
function declaration that they supposedly decorate.

I understand that doing things this way has certain technical advantages,
but this is the first time I (in my short history with python) have noticed
readability being sacrificed for any reason. It makes me sad. I feel like
my favorite organic food product decided to start using preservatives and
fillers to save money.

Jeffrey
Jul 18 '05 #1
12 1072
Jeffrey Froman wrote:

[...]
Now come decorators, introducing a non-alphabetic symbol (instead of say, a
new keyword), and worst of all for readability, they come *before* the
function declaration that they supposedly decorate.

I understand that doing things this way has certain technical advantages,
but this is the first time I (in my short history with python) have noticed
readability being sacrificed for any reason.


I think those pushing the syntax with decorators *before* the function
def believe that *that approach* provides greater readability. This
isn't an argument about whether or not decorators should be readable,
but about what constitutes readability. Obviously this is largely a
matter of opinion.

I think putting them before the def right now is probably going to
be seen by those folks as more readable, largely because they are
not used to having decorators at all, so having them stand out right
up front seems best.

This is like the third, center brake light on cars though --
once every car had them, they stopped standing out quite so
much, but it's too late to remove them now.

After a while, when everyone is used to decorators, it won't
be important to have them way out front like that, and they
could just as well, and perhaps more readably (at that time),
be moved to after the def.

Unfortunately, whatever we start with will stick, so they
will always be out front even though the advantages of that
position will have evaporated.

I say look to the future and realize that after a period of
adaptation, we'll all be just as capable of spotting decorators,
especially if they are still @ or | prefixed, if they come
after the def, as in list-after-def or as in this:

def func(some, arguments, that, might=span,
multiple=lines):
| staticmethod
| foobarbaz(x=5)
| doc('''A sample function''')
# and the body goes here

Yes, I know, people might think those lines are executed
in the body of the function, every time through. Well, those
people obviously didn't notice the decorator syntax, or read
about decorators, so it's not important whether or not they
think that, because they clearly won't understand anything about
the function at this point.

Those who know about decorators will know, as with some of the
other warts of Python, that they are executed *after* the
function is defined, not on execution.

-Peter
Jul 18 '05 #2
Am Montag, 9. August 2004 18:03 schrieb Peter Hansen:
After a while, when everyone is used to decorators, it won't
be important to have them way out front like that, and they
could just as well, and perhaps more readably (at that time),
be moved to after the def.


I don't think this is true... Decorators are not simply "meta-data" that is
attached to a function, they change the functions behaviour. As such, they
create a different function than the one which is declared.

Consider:

def somedecorator(f):
def fdec(*args,**kwargs):
return f("somearg",*args,**kwargs)
return staticmethod(fdec)

With definitions:

class x(object):

def y(some,arg):
@ somedecorator
<blah>

Versus:

class x(object):

@ somedecorator
def y(some,arg):
<blah>

Now, say you folded out the body of x with some form of decent editor. In the
first example, @somedecorator disappears, as it is part of the function body,
in the second example, it stays in (and I wouldn't want an editor to fold out
the decorating statements for a function, and it would be kind'a hard to have
a sensible way for the editor to display the first few lines decorating the
function inside the function body while the function is folded out).

What the catch is: somedecorator does not only change the function "type", as
you would consider staticmethod or classmethod do, but also changes the
function signature, as the first argument to the function is fixed by the
decorator (I actually have use cases for this).

Now, it is very important that at first glance you see that the function only
takes one parameter (as it is decorated by somedecorator), and this only
stands out clearly in the second example (at least for my taste), if you know
what somedecorator does, obviously.

The docstring of a function actually is only meta-data (in my taste), and thus
should remain inside the function definition.

When and how decorators do something to the method is unimportant to my taste
(they are executed after the function definition has been executed), but
visibly seeing that the decorator is being applied to the function is much
easier for the second syntax.

I won't try to throw in some form of debate about the character used to
attribute decorators, but I'm for @, because it stands out much more than |
does.

Anyway, my 2 cents...

Heiko.
Jul 18 '05 #3
Heiko Wundram wrote:
Am Montag, 9. August 2004 18:03 schrieb Peter Hansen:
After a while, when everyone is used to decorators, it won't
be important to have them way out front like that, and they
could just as well, and perhaps more readably (at that time),
be moved to after the def.
I don't think this is true... Decorators are not simply "meta-data" that is
attached to a function, they change the functions behaviour. As such, they
create a different function than the one which is declared.

Consider:
class x(object):
def y(some,arg):
@ somedecorator
<blah>

Versus:

class x(object):
@ somedecorator
def y(some,arg):
<blah>

Now, say you folded out the body of x with some form of decent editor. In the
first example, @somedecorator disappears, as it is part of the function body,


Actually, the first example could just as well have been this:

def y(some, arg)
@ somedecorator
:
<blah>

But I can just hear the arguments against that, much as I like it.
in the second example, it stays in (and I wouldn't want an editor to fold out
the decorating statements for a function, and it would be kind'a hard to have
a sensible way for the editor to display the first few lines decorating the
function inside the function body while the function is folded out).
I *would* like decorators to be folded, I think, if I were in the habit
of using folding editors. But I'm fairly sure it wouldn't be hard to
avoid folding @ lines that immediately follow the :, or for that matter
that come just before it. The real issue here (not that it bothers me)
is that a lot of editors are probably tied to the idea that the : comes
right after the argument list or something, so they probably would have
to be redone to handle pre-colon decorators.
The docstring of a function actually is only meta-data (in my taste), and thus
should remain inside the function definition.
This argument makes no sense to me. Why should any meta-data be inside
the function body? There should probably be one place where all
meta-data is defined, and it should be used consistently for everything,
docstrings included. (The pie-syntaxians are heading that way, it
seems.)
When and how decorators do something to the method is unimportant to my taste
(they are executed after the function definition has been executed), but
visibly seeing that the decorator is being applied to the function is much
easier for the second syntax.


To tell the truth, I think I prefer the current approach, where the
function is clearly, explicitly decorated *after* it has been defined,
and no new syntax is required.

Python is clearly on a huge evolutionary surge and conservative views
on the matter are definitely not winning out right now. And the usual
argument (submit a patch!) doesn't really work when those who want to
avoid many changes try it... I've been *not* submitting a patch on
lots of changes to Python, but somehow it's never been accepted. ;-)

-Peter
Jul 18 '05 #4
Am Montag, 9. August 2004 20:07 schrieb Peter Hansen:
Heiko Wundram wrote:
The docstring of a function actually is only meta-data (in my taste), and
thus should remain inside the function definition.
This argument makes no sense to me. Why should any meta-data be inside
the function body? There should probably be one place where all
meta-data is defined, and it should be used consistently for everything,
docstrings included. (The pie-syntaxians are heading that way, it
seems.)


Basically, what I was trying to say:

decorators aren't necessarily meta-data. decorators may return a new function
object which does something different than the actual function in question.
Thus, you could divide decorators into two categories:

1) mutating decorators, which change the function object to be a new function
(and thus introduce new functionality),

2) "decorating" decorators, which add information to the presented function
object.

Docstrings are a decorator which falls into category 2, the example I gave
falls into category 1. What my argument basically was:

Decorators which fall into category 2 may safely be hidden from the
programmer, as they only give "meta-information" on the function in question,
and don't change it's behavior, whereas decorators which fall into category 1
may not be hidden from the programmer, as they change the functions behavior,
and are thus important for understanding the function in question when
reading the code.

Now, what I'd like to see (hypothetically) is to have decorators which mutate
the function before the actual function, because they are "equivalent" to
defining a function, whereas decorators which do "decorating" inside the
function body (like the doc-string), because they are equivalent to setting
an attribute on the function.

Now, certainly, making a distinction between the two is inappropriate, as it
would only complicate code, but "hiding" mutating decorators inside the
function body is also not the right way to go, so for me, it's clear that
decorators should always be outside the function body.

But, I hold no grudge against keeping the doc-string inside the actual
function (because this actually is meta-data, it has no influence on running
the function), so the following is out of the question for me:

@doc("my doc-string")
def f():
<blah>
To tell the truth, I think I prefer the current approach, where the
function is clearly, explicitly decorated *after* it has been defined,
and no new syntax is required.
True, I use this approach a lot. But decorating a function with a clear sign
before the actual method (@<somedecorator>) only makes the code more readable
for me. As I've stated elsewhere, I've ported some code of mine to use
decorators for 2.4, and I've really felt that the code became quite a bit
more readable just by having this little bit of syntactic sugar.
Python is clearly on a huge evolutionary surge and conservative views
on the matter are definitely not winning out right now.


And that's fine. :-) Conservatism never did anybody any good. ;-)

Anyway, hope that clears up my position...

Heiko.
Jul 18 '05 #5
> And the usual argument (submit a patch!) doesn't really work when those
who want to avoid many changes try it... I've been *not* submitting a
patch on lots of changes to Python, but somehow it's never been
accepted. ;-)

-Peter


QOTW!!

I have to say though, that @ decorators are starting to grow on me
even though I was strongly against that syntax at first.

-param
Jul 18 '05 #6
Paramjit Oberoi wrote:
I have to say though, that @ decorators are starting to grow on me
even though I was strongly against that syntax at first.


Personally, I'm seeing more and more usefulness in decorators as the
discussion progresses, and I'm seeing more reasons why the most obvious
alternatives to the currently proposed syntax are not optimal. But I
still find the current syntax to be *extremely* (painfully)
uncomfortable -- this sort of prefix syntax is unlike anything else *I*
can think of in Python.

I'm particularly worried about the proposals of using this as metadata
for things like author -- that seems to be begging for almost every
function to use half a dozen or more decorators (accepts, returns,
author, design date, last revision date, etc., etc.) which will (IMO)
seriously degrade code readability. (This syntax is okay for one or two
decorators, but more than that quickly becomes obfuscatory.)

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #7
Jeff Shannon wrote:
Personally, I'm seeing more and more usefulness in decorators as the
discussion progresses, and I'm seeing more reasons why the most obvious
alternatives to the currently proposed syntax are not optimal. But I
still find the current syntax to be *extremely* (painfully)
uncomfortable -- this sort of prefix syntax is unlike anything else *I*
can think of in Python.
That's precisely my feeling at this point as well. Oddly
enough, I think with the slight change to use | instead of
@ (or perhaps even Barry's preferred =) it would be easier to
swallow. Fundamentally though it is things like the strangeness
of these lines that are somehow "bound" to the following (next)
function definition, yet have no connection to it other than
coming at the same indentation level. (At least the | syntax
does feel like it has a visual "link" to the following def.)

And the reversed order of application (non-intuitive, I feel).

And the restriction to dotted names instead of arbitrary expressions,
making it feel even more weird and non-Pythonic (and that in spite
of the workarounds that have been shown for perhaps all cases
anyway).

And other subtleties.
I'm particularly worried about the proposals of using this as metadata
for things like author -- that seems to be begging for almost every
function to use half a dozen or more decorators (accepts, returns,
author, design date, last revision date, etc., etc.) which will (IMO)
seriously degrade code readability. (This syntax is okay for one or two
decorators, but more than that quickly becomes obfuscatory.)


This paragraph also seemed worth leaving in. :-)

-Peter
Jul 18 '05 #8
>
I'm particularly worried about the proposals of using this as metadata
for things like author -- that seems to be begging for almost every
function to use half a dozen or more decorators (accepts, returns,
author, design date, last revision date, etc., etc.) which will (IMO)
seriously degrade code readability. (This syntax is okay for one or two
decorators, but more than that quickly becomes obfuscatory.)


But isn't that so of any of the alternative syntaxes. Looks to me as
if it is." Looks" as in "that is what my eyes tell me".

Only more restriction on the use of decorators - which doesn't seem to
be in the spirit of what decorators are about -or more support outside
of the @decorator framework for the common cases mitigates this issue.

Guido made the point today that at some point Python will have
optional static typing, and at that point a class of anticipated
common use cases for @decorator will be obsoleted. But that some
point is Python3000, which is anybodies guess when.

Perhaps Python is a bit pre-pubescent. and will need to endure a few
ugly years - as many of us ourselves did.

I, for one, turned out beautiful in the end.

Art
Jul 18 '05 #9
Arthur wrote:
I'm particularly worried about the proposals of using this as metadata
for things like author -- that seems to be begging for almost every
function to use half a dozen or more decorators (accepts, returns,
author, design date, last revision date, etc., etc.) which will (IMO)
seriously degrade code readability. (This syntax is okay for one or two
decorators, but more than that quickly becomes obfuscatory.)


But isn't that so of any of the alternative syntaxes. Looks to me as
if it is." Looks" as in "that is what my eyes tell me".


Like I said, I can see the reasons why the alternatives are being
rejected. But while I can see why those are being rejected, I'm not
seeing this one as all that much better -- which suggests to *me* that
maybe they should *all* be rejected.

I understand that decorators are beneficial. I understand that "Now is
better than never." But I can't help but *also* think that "...never is
often better than *right* now." Sometimes *not* including a useful
feature is better than including it in an ungainly or awkward way.
(This seems, to my mind, to be especially true of features that are
principally syntactic sugar, as it seems that @decorators are.)

I know that this has been being discussed for a long time, and nobody's
come up with a better syntax. But I remain unconvinced that the
@-syntax is a significant enough improvement over the current
(rebind-after-function-body) syntax to warrant a significant change in
the way that Python code will be structured.

(It seems, however, that GvR *is* convinced of that very thing, so all
of this is just whistling in the wind...)

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #10
On Mon, 09 Aug 2004 19:49:38 -0400, Peter Hansen <pe***@engcorp.com> wrote:
Jeff Shannon wrote:
Personally, I'm seeing more and more usefulness in decorators as the
discussion progresses, and I'm seeing more reasons why the most obvious
alternatives to the currently proposed syntax are not optimal. But I
still find the current syntax to be *extremely* (painfully)
uncomfortable -- this sort of prefix syntax is unlike anything else *I*
can think of in Python.

If the '@' or '|' were a composite glyph instead, and moved a little (to the other
end of the function expression), the "prefix" aspect would look more like
the function call that it is sugar for, e.g., using '(:'

deco1(:
deco2(:
def foo():
pass
# ':):)' closing "parens" not required

Thus the order is also plain, i.e.,
foo = deco1(deco2(foo)))

Or if the colon in '(:' messes up tools, maybe '(%' or '(=' ?
.... or '(-;' ?
*<8^P
That's precisely my feeling at this point as well. Oddly
enough, I think with the slight change to use | instead of
@ (or perhaps even Barry's preferred =) it would be easier to
swallow. Fundamentally though it is things like the strangeness
of these lines that are somehow "bound" to the following (next)
function definition, yet have no connection to it other than
coming at the same indentation level. (At least the | syntax
does feel like it has a visual "link" to the following def.)

And the reversed order of application (non-intuitive, I feel). Does (: as above help?
And the restriction to dotted names instead of arbitrary expressions,
making it feel even more weird and non-Pythonic (and that in spite
of the workarounds that have been shown for perhaps all cases
anyway). Yes. With (: it could be legal as a special function-calling expression trailer
and would call whatever any preceding expression yielded (and obviously fail if
it wasn't callable).

And other subtleties.
I'm particularly worried about the proposals of using this as metadata
for things like author -- that seems to be begging for almost every
function to use half a dozen or more decorators (accepts, returns,
author, design date, last revision date, etc., etc.) which will (IMO)
seriously degrade code readability. (This syntax is okay for one or two
decorators, but more than that quickly becomes obfuscatory.)

Some of that sounds like rfc822 stuff ...
This paragraph also seemed worth leaving in. :-)


I'm still wondering what aegis decorators will eventually "unify" under,
and with what ;-) Orthogonality beats special-casing IMO ;-)

Regards,
Bengt Richter
Jul 18 '05 #11
In article <Xq********************@powergate.ca>,
Peter Hansen <pe***@engcorp.com> wrote:

Python is clearly on a huge evolutionary surge and conservative views
on the matter are definitely not winning out right now. And the usual
argument (submit a patch!) doesn't really work when those who want to
avoid many changes try it... I've been *not* submitting a patch on
lots of changes to Python, but somehow it's never been accepted. ;-)


I think you are right, Peter, about the pressure to change the nature of
Python, and the resistance to conservatism about doing so.

I have been following the explosion of discussion on this subject with
some concern, because I think this whole "decorators" proposal is a
misguided attempt to conflate several orthogonal goals under the aegis
of a single new mechanism. I do not believe it is wise to aggregate the
notations for descriptive meta-data (author, version number, etc.) with
those of type-constraints, of method qualifiers, or any other such
code-generation annotations.

Much of the discussion has focused on the visual appearance of this new
construct, but I think that's a red herring -- its problems run much
deeper than that. Even assuming we can find a suitably harmonious
notation for it, I remain unconvinced that "decorators" as currently
specified deserve to be added to Python. Assuming we take the Zen of
Python as a set of philosophical design goals for Python, I argue that
all the proposed uses of decorators so far fail the Zen on the following
axes: Beauty, Simplicity, Sparseness, Readability, Special Cases, One
Obvious Way, and Difficulty of Explanation.

The stated Motivation of PEP-318 is, essentially, to visually conjoin
the translation of functions into class or static methods with the
definition of the function itself. Oh, and by the way, maybe we could
also use this for some other annotations we'll think up later -- but
for now, that's pretty much it (http://www.python.org/peps/pep-0318.html).
Do we really need this small change so badly that we're willing to open
the door to every half-baked hunk of function and method meta-data
somebody can imagine?

Let's stop bickering about syntax for a moment, take a deep breath, and
back up a pace. Does Python really need this? I say no: Even if we
come up with a good syntax, I do not think decorators, as they are being
described and implemented as we speak, are a good idea. Some of the
ideas people want to use them for are reasonable, but I think we should
be rational about it, and keep orthogonal concerns appropriately
separated.

-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #12
Michael J. Fromberger wrote:
Assuming*we*take*the*Zen*of
Python as a set of philosophical design goals for Python, I argue that
all the proposed uses of decorators so far fail the Zen on the following
axes:**Beauty,*Simplicity,*Sparseness,*Readability ,*Special*Cases,*One
Obvious Way, and Difficulty of Explanation.


Exactly so. Apparently for the people who design Python, however, this is
not a philosophy but a joke (note that it's in the Humor section at
python.org.)

For me, however, it's not a joke. I choose python because it reflects
choices I make for my life as a whole. To this end, I do still have
recourse without having to abandon python yet:

I will keep the Zen; I will boycott decorators.

If it is true (as it has been asserted in this newsgroup and elsewhere) that
the vast majority of python developers do not like decorators, then
boycotting them will make them go away despite all efforts to introduce
them. Avoid using them. Avoid (or "fix") code that uses them.

Ultimately, what goes into python code is up to those of us who write the
code.

Jeffrey
Jul 18 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

28
by: Anthony Williams | last post by:
Good morning, I'm currently designing a site, using CSS, and wish to create a variable width two-column layout, with header and footer, and one fixed-width column on the left. Previously, I...
7
by: Atul Malaviya | last post by:
>From a design/usability perspective. When will one use a singleton pattern and when a class with purely static members? What are the pros and cons? I have inherited a code base which is full...
13
by: RK | last post by:
I apologize if this is a stupid question, I'm asking Python group for perspective on Ruby, but I don't see how the alternative of going to a ruby group for a perspective on Ruby is going to do me...
11
by: Sumitava(Asteroid) | last post by:
I intend to provide (write) a library in C++ to simulate emotions. Please suggest me the inputs and outputs the bulk of programmers would want to simulate emotions. What I am doing is a requirement...
1
by: Kamilche | last post by:
I have a need to tile a bitmap across an arbitrary quadrilateral, and apply perspective to it. The Python Imaging Library (PIL) has an undocumented function that might work, but I can't figure out...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.