RE: [Python-Dev] Re: new syntax for wrapping (PEP 318)

Jim Jewett writes: [I'm not going to quote him... details at http://mail.python.org/pipermail/python-dev/2004-February/042685.html ] Jim, thank you for putting this so clearly. I want to second just about everything that you said. Since you've gone into it in great detail, I'll try the brief, bullet-points version: The "def name [modifiers]:" is unpythonic because: * It re-uses the "[]" for a completely new purpose, unrelated to lists or indexing. * It relies heavily on punctuation (the placement of the ":"). * It doesn't "read like english". * There's no good way for a newbie to look it up. All of these would be addressed by using a keyword. The only objection seems to be "we couldn't find a word we all liked". But that's hardly a good reason to go with pure punctuation. Me, personally, I like "as". It works great for wrappers like classmethod, and is a sufficiently generic word that it wouldn't offend my sense of grammer when used with other kinds of wrappers. But like Jim I'm not strongly in favor of any particular keyword, just against the use of pure punctuation. -- Michael Chermside

Michael> The "def name [modifiers]:" is unpythonic because: Michael> * It re-uses the "[]" for a completely new purpose, unrelated Michael> to lists or indexing. Not necessarily. It names a list of functions to be applied to this function to get the final definition (I'll leave it to others to figure out the order of application :-). In particular, you could probably dream up some rather "interesting" list constructors which would allow the programmer (or even the user) to modify the behavior at function definition time: def is_enabled(m, fname, tracers=os.environ.get("TRACERS", "")): "ex: TRACERS=func1:trace,func2:count_lines ; export TRACERS" return tracers.find("%s:%s"%(fname,m.__name__)) != -1 modifiers = [trace, profile, count_lines] def func1(a,b,c) [m for m in modifiers if is_enabled(m, "func1")]: ... def func2(a,b,c) [m for m in modifiers if is_enabled(m, "func2")]: ... that it would necessarily be good to always use such complex constructs, but it might provide some as-yet-unanticipated power for debugging or other magic. If you are going to add [...] as a function modifier syntax, I would argue that it should allow the full power of list (or generator) comprehensions. Michael> * It relies heavily on punctuation (the placement of the Michael> ":"). The placement of the ":" hasn't changed. It's still at the end. A list constructor was just stuffed in between the argument list and the colon. Michael> * It doesn't "read like english". No doubt, but then not everything in Python does. Michael> * There's no good way for a newbie to look it up. How about in the language reference manual section on function definitions? I don't think every bit of the language needs to be tagged with a keyword so that people can more easily search the documentation. How do people find out about operator precedence? How do people learn about function names with leading underscores or leading and trailing double underscores? The language manages to succeed even though the most frequently used function name in Python is probably "__init__" and that the most common sorts of expressions are keyword-free. A newbie won't know off-the-bat what the "__"s mean and even though non-programmers will probably never have seen the "**" operator, they still manage to figure it out. Michael> All of these would be addressed by using a keyword. The only Michael> objection seems to be "we couldn't find a word we all Michael> liked". But that's hardly a good reason to go with pure Michael> punctuation. I think another keyword would be pretty superfluous. Function modifiers would be a fairly advanced feature anyway (I personally have yet to use classmethod or staticmethod), so the extra keyword would probably be unnecessary for most people reading and needing to truly understand a bit of code. If they are deemed not all that advanced, they should probably be discussed in the tutorial. Skip

On Feb 25, 2004, at 4:02 PM, Skip Montanaro wrote:
Michael> The "def name [modifiers]:" is unpythonic because: Michael> * It re-uses the "[]" for a completely new purpose, unrelated Michael> to lists or indexing.
Not necessarily. It names a list of functions to be applied to this function to get the final definition (I'll leave it to others to figure out the order of application :-). In particular, you could probably dream up some rather "interesting" list constructors which would allow the programmer (or even the user) to modify the behavior at function definition time:
def is_enabled(m, fname, tracers=os.environ.get("TRACERS", "")): "ex: TRACERS=func1:trace,func2:count_lines ; export TRACERS" return tracers.find("%s:%s"%(fname,m.__name__)) != -1
modifiers = [trace, profile, count_lines]
def func1(a,b,c) [m for m in modifiers if is_enabled(m, "func1")]: ...
def func2(a,b,c) [m for m in modifiers if is_enabled(m, "func2")]: ...
that it would necessarily be good to always use such complex constructs, but it might provide some as-yet-unanticipated power for debugging or other magic. If you are going to add [...] as a function modifier syntax, I would argue that it should allow the full power of list (or generator) comprehensions.
I agree with you here, but the patch doesn't do that yet. Right now you would need to do something like: def fnseq(lst): def fnseq(fn): for obj in lst: fn = obj(fn) return fn return fnseq def func1(a,b,c) [fnseq([m for m in ...])]: -bob

On Wed, 2004-02-25 at 21:02, Skip Montanaro wrote:
I think another keyword would be pretty superfluous. Function modifiers would be a fairly advanced feature anyway (I personally have yet to use classmethod or staticmethod), so the extra keyword would probably be unnecessary for most people reading and needing to truly understand a bit of code. If they are deemed not all that advanced, they should probably be discussed in the tutorial.
Just a data point from a user: I use classmethod fairly frequently, and I would *love* to see some syntax to support it. As has been pointed out before, classmethod (and staticmethod) are a part of the interface of a function, and shouldn't be tacked on to the end of the body. Please let me put them where people (and hopefully pydoc and pychecker) can easily see them. I marginally prefer [] to "as", but I don't have strong feelings either way. Both seem quite readable and pythonic to me. Mark Russell

Just a data point from a user: I use classmethod fairly frequently, and I would *love* to see some syntax to support it. As has been pointed out before, classmethod (and staticmethod) are a part of the interface of a function, and shouldn't be tacked on to the end of the body. Please let me put them where people (and hopefully pydoc and pychecker) can easily see them.
I personally don't see the point of using any syntax for wrapping a function like so: class a: def funct(self): pass a = classmethod(a) If we actually test this:
class a: ... def a(self): ... pass ... def b(self): ... pass ... def c(self): ... pass ... a = classmethod(a) ... b = staticmethod(b) ... foo = a() type(foo.a) <type 'instancemethod'> type(foo.b) <type 'function'> type(foo.c) <type 'instancemethod'>
It is entirely possible that I'm missing something, but according to Python 2.3.2, foo.a and foo.c are the same kind of thing, who am I to disagree? For another data point, I've never had to use staticmethod or classmethod in my code, and have never needed to use function decorators. In general, I am against the use of arbitrary syntax like the following; class foo: def a(self) [...]: #body def b(self) <...>: #as paul recently suggested #body Mostly because it leads to newbies asking what the hell it means. You only need to check the c.l.py newsgroup to discover 3-4 messages/week asking about the meaning of *args and **kwargs. If either of the above were allowed, new (and seasoned users for a while) would ask, "what does this thing mean, I've never seen anything like it before?" Honesly, a new (or used) keyword would make the most sense, perhaps "as", which has been offered before. At least then people could check the documentation index for "as" and get two listings, one for import statements, and one for decorator syntax. I think something like the following would make the most sense (it includes the opportunity for multi-line decorators as Barry suggests). class foo: def a(self) as [...]: #body Even though I think the above is the best syntax I've seen so far, that doesn't mean that I like it. Personally, I don't have any use for decorators currently, and could see new and old users of Python being stymied by examples of this in new code. Being able to reverse the application order of the decorators, and still have it make sense to a not-insignificant number of people, means that it could be confusing. I understand its application in PyObjC and in the use of staticmethod, but for the vast majority of users, I doubt that adding it would result in use. Certainly it seems like a chicken and egg problem (there are a few of those being discussed in c.l.py currently), but in all the code I've read "in the wild", I've never once seen anyone manually apply decorators to functions. I suggest a supporter of the PEP take a look through the standard library. If there exists a non-trivial number of examples of its use, maybe my opinion would change. On the other hand, if in the standard library, there exists some _very small number_ of examples of manual decorators, then perhaps this is application-specific. I have a feeling that including application-specific /syntax/ in Python is frowned upon. - Josiah

On Wed, 2004-02-25 at 21:56, Josiah Carlson wrote:
I personally don't see the point of using any syntax for wrapping a function like so:
class a: def funct(self): pass a = classmethod(a)
In a short example like this, you're right that it may not help much. But I've written a bunch of code that uses staticmethod or transformations of (some) methods in a class. When your method is three quarters of a page long, the separation between the function definition and the decoration is a readability burden. What I tend to do in that case is name the function with an underscore and use the 'public' name for th wrapped attribute. This is still less readable that it should be because that little "foo = wrapper(_foo)" line can easily get lost. I've rewritten some of my code to use both the [] and the 'as' syntax. Neither is ideal, primarily because the interesting information tends to get pushed way off to the right, where I think the eye is lazier because of the more ragged nature of "code right". Putting the decorator between the def and the method name actually doesn't look so bad to me, e.g.: def [classmethod] func(a, b, c): but I think with a longer decorator list, it might be problematic. I think that one element decorator lists will be the most common use and in that case, I like this syntax because it almost reads like English. E.g. "define a classmethod called func taking arguments a, b, and c".
Honesly, a new (or used) keyword would make the most sense, perhaps "as", which has been offered before. At least then people could check the documentation index for "as" and get two listings, one for import statements, and one for decorator syntax.
I agree with whoever said that people aren't going to look up 'as', they are going to look up 'def' when trying to understand what this stuff means.
Even though I think the above is the best syntax I've seen so far, that doesn't mean that I like it. Personally, I don't have any use for decorators currently, and could see new and old users of Python being stymied by examples of this in new code.
Actually stuff 'like this' makes for some much more elegant Python idioms. I think the features are just so new that it hasn't really made its way into much released production code. I think Python 2.4 is the right time frame for improving the utility of this very neat feature. -Barry

On Feb 25, 2004, at 9:56 PM, Josiah Carlson wrote:
Just a data point from a user: I use classmethod fairly frequently, and I would *love* to see some syntax to support it. As has been pointed out before, classmethod (and staticmethod) are a part of the interface of a function, and shouldn't be tacked on to the end of the body. Please let me put them where people (and hopefully pydoc and pychecker) can easily see them.
I personally don't see the point of using any syntax for wrapping a function like so:
class a: def funct(self): pass a = classmethod(a)
This just isn't valid Python code.. but anyways :)
If we actually test this:
class a: ... def a(self): ... pass ... def b(self): ... pass ... def c(self): ... pass ... a = classmethod(a) ... b = staticmethod(b) ... foo = a() type(foo.a) <type 'instancemethod'> type(foo.b) <type 'function'> type(foo.c) <type 'instancemethod'>
It is entirely possible that I'm missing something, but according to Python 2.3.2, foo.a and foo.c are the same kind of thing, who am I to disagree?
What does the type(object) have to do with anything? I thought people have learned by now that it's not wise to use type for much of anything. You should instead opt for (at least) isinstance(..), getattr(...) or preferably a more robust adaptation solution such as Zope X3's components, Twisted's components, or PyProtocols (a subproject of PEAK).
For another data point, I've never had to use staticmethod or classmethod in my code, and have never needed to use function decorators.
I never had to use Python either, but I think it's a great language that let's me work more effectively. There's nothing I can do in Python that I couldn't have done in another language, well, except enjoy writing code :)
In general, I am against the use of arbitrary syntax like the following;
class foo: def a(self) [...]: #body def b(self) <...>: #as paul recently suggested #body
Mostly because it leads to newbies asking what the hell it means. You only need to check the c.l.py newsgroup to discover 3-4 messages/week asking about the meaning of *args and **kwargs. If either of the above were allowed, new (and seasoned users for a while) would ask, "what does this thing mean, I've never seen anything like it before?"
Honesly, a new (or used) keyword would make the most sense, perhaps "as", which has been offered before. At least then people could check the documentation index for "as" and get two listings, one for import statements, and one for decorator syntax. I think something like the following would make the most sense (it includes the opportunity for multi-line decorators as Barry suggests).
class foo: def a(self) as [...]: #body
Even though I think the above is the best syntax I've seen so far, that doesn't mean that I like it. Personally, I don't have any use for decorators currently, and could see new and old users of Python being stymied by examples of this in new code. Being able to reverse the application order of the decorators, and still have it make sense to a not-insignificant number of people, means that it could be confusing.
I am fine with the "as" keyword. I don't really know how 'newbies' think, and an extra 4 characters for clarity doesn't bother me at all. Not having this syntax requires A WHOLE !@#$*( lot of verbosity and repetition, or drastic measures such as alternative compilers (Quixote) or really awful terrible introspection hacks (PEAK does stack introspection). I don't really care, as long as it makes usage much shorter than it is currently. I need this syntax, and I will maintain my own patched version of Python or alternate compiler if I have to (which is less effort than writing code that has to use existing grammar), but I would VERY much rather not.
I understand its application in PyObjC and in the use of staticmethod, but for the vast majority of users, I doubt that adding it would result in use. Certainly it seems like a chicken and egg problem (there are a few of those being discussed in c.l.py currently), but in all the code I've read "in the wild", I've never once seen anyone manually apply decorators to functions.
The vast majority of Python programmers either learned Python before it had decorators, hasn't read the documentation for it, or just aren't writing the kind of code that needs it. We have these great new style classes now, but it's hard to make any good use of them if it's not simple to create descriptors and tag things with metadata.
I suggest a supporter of the PEP take a look through the standard library. If there exists a non-trivial number of examples of its use, maybe my opinion would change. On the other hand, if in the standard library, there exists some _very small number_ of examples of manual decorators, then perhaps this is application-specific. I have a feeling that including application-specific /syntax/ in Python is frowned upon.
This isn't at all fair, most (almost all?) of the standard library was written before Python had any decorators, by people who wanted backwards compatibility (for the most part). Additionally, the current grammar makes decorators so !@#$ inconvenient that nobody wants to use them unless they have to. Look no further than any PEAK or PyObjC project to see plenty of decorators. Especially PEAK. Off the top of my head, this new syntax would be extremely convenient for *at least* the following projects and software that uses them: ctypes Zope X3 Twisted PEAK / PyProtocols PyObjC (these two are guesses, I can't say this from experience) SQLObject Quixote PyObjC and ctypes need the syntax the most, because both projects attempt to make low-level libraries easier to extend and use by creating a domain specific languages within Python. Currently, this is only a partial success because defining functions and methods is actually harder than in ObjC or C respectively due to this severe limitation in Python's grammar. These projects could be extremely popular if they were nicer to use. As far as numbers go, I guarantee you that once this syntax exists, people (at least anyone who uses descriptors and doesn't need backwards compatibility) will start using it in droves. If not "vast majority users", at least framework/library writers... you know, the people writing the software that gets new users and business types excited about Python. As a bonus, some big abusers of lambda such as PEAK (~333 uses), Twisted (~268 uses), and the standard library (~295 uses) may end up using this syntax instead, because it covers some of the use cases where what you want is really some kind of "anonymous code block". -bob

At 10:51 PM 2/25/04 -0500, Bob Ippolito wrote:
Not having this syntax requires A WHOLE !@#$*( lot of verbosity and repetition, or drastic measures such as alternative compilers (Quixote) or really awful terrible introspection hacks (PEAK does stack introspection).
Actually, that's only for class decoration. PEAK does method decoration the old fashioned way, i.e.: class Something: def aMethod(self): .... aMethod = binding.Make(aMethod) So, an accepted function decorator syntax will make this sort of thing clearer for PEAK as well.

On Feb 26, 2004, at 12:14 PM, Phillip J. Eby wrote:
At 10:51 PM 2/25/04 -0500, Bob Ippolito wrote:
Not having this syntax requires A WHOLE !@#$*( lot of verbosity and repetition, or drastic measures such as alternative compilers (Quixote) or really awful terrible introspection hacks (PEAK does stack introspection).
Actually, that's only for class decoration. PEAK does method decoration the old fashioned way, i.e.:
class Something: def aMethod(self): ....
aMethod = binding.Make(aMethod)
So, an accepted function decorator syntax will make this sort of thing clearer for PEAK as well.
Thanks for correcting me here, I was indeed referring to class decoration using stack introspection. The currently-being-debated patch includes this as well with the same syntax. -bob

Josiah Carlson wrote:
...
I suggest a supporter of the PEP take a look through the standard library. If there exists a non-trivial number of examples of its use, maybe my opinion would change. On the other hand, if in the standard library, there exists some _very small number_ of examples of manual decorators, then perhaps this is application-specific. I have a feeling that including application-specific /syntax/ in Python is frowned upon.
Here are the "applications" I've used that I think could benefit from the syntax: * Pyrex type declaration syntax (extends the Python syntax) * * PTL (extends the Python syntax and docstrings) * http://www.mems-exchange.org/software/quixote/doc/PTL.html * SPARK (abuses docstrings) * http://gnosis.cx/publish/programming/charming_python_b6.html * Grouch (abuses class docstrings) * http://www.mems-exchange.org/software/grouch/ * XPath callbacks (abuses docstrings) * http://mail.python.org/pipermail/xml-sig/2000-March/002008.html * Python COM (and XPCOM) servers (separate metadata from functions) * http://mail.python.org/pipermail/python-list/2001-December/075488.html * Zope ZPublisher * http://www.zope.org/Members/Amos/ExtendingZopeSlides.html#11 When a feature is emulated over and over that's a strong hint that the industry is asking for first-class support. Paul Prescod

Here are the "applications" I've used that I think could benefit from the syntax:
[snip...] You (and others) have convinced me. There exists a reasonably large number of use-cases, even if I don't have one. The real question is whether everyone can decide on a good syntax. I will make one request; almost anything but the below. def staticmethod decorator1 decorator2 decorator3 funct(arg): It makes finding the name of the function more work than it should be. - Josiah

On Feb 26, 2004, at 2:43 AM, Josiah Carlson wrote:
Here are the "applications" I've used that I think could benefit from the syntax:
[snip...]
You (and others) have convinced me. There exists a reasonably large number of use-cases, even if I don't have one. The real question is whether everyone can decide on a good syntax. I will make one request; almost anything but the below.
Great :)
def staticmethod decorator1 decorator2 decorator3 funct(arg):
It makes finding the name of the function more work than it should be.
I prefer them after the argument list as well. -bob

On Thu, 2004-02-26 at 02:43, Josiah Carlson wrote:
You (and others) have convinced me. There exists a reasonably large number of use-cases, even if I don't have one. The real question is whether everyone can decide on a good syntax.
We won't, so if the PEP's accepted, the BDFL will do it for us. That's why we keep him around <wink>. -Barry

I'm not too concerned about the syntax. All current proposals weigh about equal to me. Although I don't believe "as" makes documentation lookup much easier. I think this feature will be another one of those positive changes that effects the entire way python is used. The kind of thing like iterators, string methods, etc. I've been playing with the idea for awhile and can throw out some extra use cases. Some of these may even be bad ideas apon further thought, but it's something to ponder. def main() [__main__]: """specify a function to be run if __name__=='__main__'. this would need some other python tricks to actually work.""" def cleanup() [sys.atexit]: """ensures this function is called when program quits.""" def handler(event) [self.button.slot('clicked')]: """automatically make this function a callback for some gui slot/signal mechanism.""" def food(arg) [pysco.optimize]: """specifically control functions that psyco takes over.""" def bard(arg, gar) [validate(int, str)]: """confirm arguments match a type. validate would have to be a function that returns a function. odd.""" def corn() [profiler.track]: """log specific runtime stats on this function.""" def sanitytest() [sys.debugfunc]: """function is ignored at runtime if python not in "-O" optimize mode (something like assert).""" def entrypoint(data) [__all__]: def hidden(data) [__hidden__]: """select functions for hiding or passing to 'import *'.""" I'm sure others will come to me as soon as I hit send. I don't know if I get a vote, but I'm +2 on PEP 318.

Pete Shinners <pete@shinners.org> writes:
I'm not too concerned about the syntax. All current proposals weigh about equal to me. Although I don't believe "as" makes documentation lookup much easier.
I think this feature will be another one of those positive changes that effects the entire way python is used. The kind of thing like iterators, string methods, etc. I've been playing with the idea for awhile and can throw out some extra use cases.
Some of these may even be bad ideas apon further thought, but it's something to ponder.
Actually, I think one of the downsides to the function decorator proposals, or at least a point that needs thought, is some of the loony things you can do with it :-) (and, like you say, the fact that this might well turn out to be a much used change). def pi_over_two() [apply]: return math.pi/2 Cheers, mwh -- A difference which makes no difference is no difference at all. -- William James (I think. Reference anyone?)

Pete> I'm sure others will come to me as soon as I hit send. I don't Pete> know if I get a vote, but I'm +2 on PEP 318. I'm +1 on the idea though with the post-arglist list-y syntax: def funct(a1, a2) [d1, d2]: pass for the same reasons Barry elaborated yesterday. The list constructor allows you to split across lines and the decorators are in some sense secondary to the function name and arguments which deserve to be displayed more prominently. Using (...) provides too little visual distinction with the function's argument list. Using <...> is tough for syntax highlighting editors because < and > are already relational operators and shouldn't visually balance in that context. Using {...} implies use of a dictionary, which in turn implies unordered application of multiple decorators. Not using any sort of bracket forces the use of backslashes to continue the decorator list across lines. Using "as" with or without any other syntactic sugar just seems like keyword noise to me. It's not necessary for the parser to disambiguate things and doesn't add much to the comprehension of the construct. If Guido is determined to add some English there we might as well go whole hog: def funct(a1, a2) modified by [d1, d2, wink(0.5)]: pass Skip

In article <c1k9fm$hrf$1@sea.gmane.org>, Pete Shinners <pete@shinners.org> wrote:
I'm not too concerned about the syntax. All current proposals weigh about equal to me. Although I don't believe "as" makes documentation lookup much easier.
I think this feature will be another one of those positive changes that effects the entire way python is used. The kind of thing like iterators, string methods, etc. I've been playing with the idea for awhile and can throw out some extra use cases.
Some of these may even be bad ideas apon further thought, but it's something to ponder.
def main() [__main__]: """specify a function to be run if __name__=='__main__'. this would need some other python tricks to actually work."""
def cleanup() [sys.atexit]: """ensures this function is called when program quits.""" ...
This looks like too much magic to me -- a recipe for making tricky and hard-to-read code. I would rather focus on the heart of PEP 318 and try to make class and static methods easier to declare, e.g. something like: def classmethod foo(self, ...): If one supports arbitrary modifier functions and lists of modifier functions I think readability is really going to suffer. I'm usually in favor of generality, but reading the examples above and others presented in this thread really makes me shudder. -- Russell

Russell> I would rather focus on the heart of PEP 318 and try to make class and Russell> static methods easier to declare, e.g. something like: Russell> def classmethod foo(self, ...): Russell> If one supports arbitrary modifier functions and lists of Russell> modifier functions I think readability is really going to Russell> suffer. -1. If you tie the specific decorators into the language syntax I think you will find it too limiting in the long run (perhaps even in the short run). I suspect many of the planned uses for such an extension will not simply be to define class or static methods. Skip

On 26-feb-04, at 3:56, Josiah Carlson wrote:
Just a data point from a user: I use classmethod fairly frequently, and I would *love* to see some syntax to support it. As has been pointed out before, classmethod (and staticmethod) are a part of the interface of a function, and shouldn't be tacked on to the end of the body. Please let me put them where people (and hopefully pydoc and pychecker) can easily see them.
I personally don't see the point of using any syntax for wrapping a function like so:
class a: def funct(self): pass a = classmethod(a)
Not that I have anything usefull to add, but ... I find the proposed syntax easier to understand than the current alternative, even for short functions. In "def foo(self) [classmethod]: pass" the [classmethod] part feels like an anotation/declaration, while "foo = classmethod(foo)" has a more magical feel. I'd expect at least as much newbe questions about the current idiom than about the alternatives. Ronald -- X|support bv http://www.xsupport.nl/ T: +31 610271479 F: +31 204416173

On Wed, 2004-02-25 at 21:02, Skip Montanaro wrote:
I think another keyword would be pretty superfluous. Function modifiers would be a fairly advanced feature anyway (I personally have yet to use classmethod or staticmethod), so the extra keyword would probably be unnecessary for most people reading and needing to truly understand a bit of code. If they are deemed not all that advanced, they should probably be discussed in the tutorial.
Just a data point from a user: I use classmethod fairly frequently, and I would *love* to see some syntax to support it. As has been pointed out before, classmethod (and staticmethod) are a part of the interface of a function, and shouldn't be tacked on to the end of the body. Please let me put them where people (and hopefully pydoc and pychecker) can easily see them. I marginally prefer [] to "as", but I don't have strong feelings either way. Both seem quite readable and pythonic to me. Mark Russell

On Feb 25, 2004, at 4:52 PM, Mark Russell wrote:
On Wed, 2004-02-25 at 21:02, Skip Montanaro wrote:
I think another keyword would be pretty superfluous. Function modifiers would be a fairly advanced feature anyway (I personally have yet to use classmethod or staticmethod), so the extra keyword would probably be unnecessary for most people reading and needing to truly understand a bit of code. If they are deemed not all that advanced, they should probably be discussed in the tutorial.
Just a data point from a user: I use classmethod fairly frequently, and I would *love* to see some syntax to support it. As has been pointed out before, classmethod (and staticmethod) are a part of the interface of a function, and shouldn't be tacked on to the end of the body. Please let me put them where people (and hopefully pydoc and pychecker) can easily see them.
I marginally prefer [] to "as", but I don't have strong feelings either way. Both seem quite readable and pythonic to me.
I'm in the same camp, I /need/ something sooner than later to make certain kinds of code usable, I don't care if it's spelled [] or as. -bob

Mark> Just a data point from a user: I use classmethod fairly Mark> frequently, and I would *love* to see some syntax to support it. Mark> As has been pointed out before, classmethod (and staticmethod) are Mark> a part of the interface of a function, and shouldn't be tacked on Mark> to the end of the body. Please let me put them where people (and Mark> hopefully pydoc and pychecker) can easily see them. Mark> I marginally prefer [] to "as", but I don't have strong feelings Mark> either way. Both seem quite readable and pythonic to me. I'll add another data point. Quixote'd PTL uses almost this exact syntax to distinguish between PTL functions/methods which return HTML or plain text. The only difference is that it places the annotation before the argument list: def head [html] (title): ''' <head> <title>%(title)s</title> ''' % locals() threecol_css() '</head>' I haven't heard any Quixote users complain about the construct. (I don't know if PTL supports more than one annotation per function or not. I think the only choices are currently "html" or "text", which are obviously mutually exclusive.) Skip

On Wed, 2004-02-25 at 22:37, Skip Montanaro wrote:
I'll add another data point. Quixote'd PTL uses almost this exact syntax to distinguish between PTL functions/methods which return HTML or plain text. The only difference is that it places the annotation before the argument list:
def head [html] (title):
I think the reason why this (and the proposed method annotation syntax) is readable is that it reads as a parenthetical note [i.e. something that is intended to convey a bit of extra information]. It would be interesting to show def foo(self) [classmethod]: to a relative python beginner and ask them the guess at the meaning. My hunch is that they would assume that "[classmethod]" modifies the meaning of the function defintion in some way. The curious could then look up classmethod in the manual, where they would presumably find a note about the [] syntax. Mark Russell

On Wed, Feb 25, 2004 at 11:33:40PM +0000, Mark Russell wrote: [...]
It would be interesting to show
def foo(self) [classmethod]:
to a relative python beginner and ask them the guess at the meaning. My hunch is that they would assume that "[classmethod]" modifies the meaning of the function defintion in some way. The curious could then look up classmethod in the manual, where they would presumably find a note about the [] syntax.
Exactly -- this is why a keyword isn't need, the decorator is the "keyword". Where Java people need to lookup "static" in their language manual, Python people will lookup "staticmethod" in the library reference. The documentation for staticmethod would presumably mention that it's a "function decorator", and link to the appropriate docs, and maybe even give an example. And regardless of "[]" vs. "as", I would expect that a confused user could read the language reference docs for function declarations (i.e. there's already a keyword for them to lookup: def!) to find out what the annotation syntax means. So, as far as I can see, "[]" vs. "as" will make no practical difference to the ease-of-documentation-lookup, so my preference is to go with the syntax that looks subjectively better to my eyes -- which is []. I don't mind "as" either, though. -Andrew.

I hate to get into this loop where a hundred syntax options are discussed, most of them having been disgarded before, but why not use angle-brackets rather than square-brackets? def foo(self) <classmethod, hiddenmethod>: pass Paul Prescod

On Wed, 2004-02-25 at 19:05, Paul Prescod wrote:
I hate to get into this loop where a hundred syntax options are discussed, most of them having been disgarded before, but why not use angle-brackets rather than square-brackets?
def foo(self) <classmethod, hiddenmethod>: pass
Of course, you meant << and >> right? :) -Barry

On Wed, Feb 25, 2004 at 04:05:50PM -0800, Paul Prescod wrote:
I hate to get into this loop where a hundred syntax options are discussed, most of them having been disgarded before, but why not use angle-brackets rather than square-brackets?
def foo(self) <classmethod, hiddenmethod>:
I haven't yet used an editor that matched angle-brackets well, especially since they are usually binary operators, not grouping characters. Think "if a < b and c > d:"... Jeff

Paul Prescod <paul@prescod.net>:
def foo(self) <classmethod, hiddenmethod>: pass
Because it looks unspeakably ugly! -1. Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+

On Wed, 2004-02-25 at 18:57, Andrew Bennetts wrote:
Exactly -- this is why a keyword isn't need, the decorator is the "keyword".
Excellent point. The other thing about using square brackets syntactically is that they allow for multiple line constructs without resorting to backslashes. def foo(a, b, c) [firstdecorator, seconddecorator, thirddecorator]: vs. def foo(a, b, c) as firstdecorator, \ seconddecorator, \ thirddecorator: -Barry
participants (15)
-
Andrew Bennetts
-
Barry Warsaw
-
Bob Ippolito
-
Greg Ewing
-
Jeff Epler
-
Josiah Carlson
-
Mark Russell
-
Michael Chermside
-
Michael Hudson
-
Paul Prescod
-
Pete Shinners
-
Phillip J. Eby
-
Ronald Oussoren
-
Russell E. Owen
-
Skip Montanaro