By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,300 Members | 1,789 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,300 IT Pros & Developers. It's quick & easy.

PEP 318: Can't we all just get along?

P: n/a
For what it's worth, I wrote the original PEP 318. I probably wasn't
qualified, but I just wanted a nice simple way to declare class methods
without having to repeat the function name. After submitting it to BDFL
for approval, more work was needed and the discussion of PEP 318 on
python-dev increased rapidly. It was evident that I was in over my head,
so I asked more someone more experienced to take over.

I guess others had bigger plans for my proposal that I had planned. It
has turned into the "solution" to many problems: type checking (both
arguments and returned values), metaclasses, metadata, interfaces,
function attributes, etc.). Unfortunately, in the process, this simple
request for syntactical sugar has turned into a monstrosity. In my
opinion, none of the proposed syntaxes really seem Pythonic. This PEP
just seems to be trying to solve too many problems.

Bear with me, but I'd like to propose one more syntax that is simple,
easy for newbies to understand, and nowhere near as powerful as the
current PEP's syntax. However, it doesn't add incoherent, arbitrary
syntax either.

def classmethod foo(x, y, z):
pass

That's it. One "decorator" that is a callable object that takes a
method as it's only argument. No expressions, lists, tuples, etc. Just
one callable object. Ok, if you absolutely must have more than one.

def classmethod synchronized foo(x, y, z):
pass

Once again, no expressions. I know that this isn't going to solve
everyone's type-checking, metadata, and function attribute problems, but
let's face it, using this PEP for all of those things just creates ugly
syntax. There must be more Pythonic ways to do those things in their
own PEPs.

--
Kevin Smith
Ke*********@sas.com
Jul 18 '05 #1
Share this Question
Share on Google+
38 Replies


P: n/a
Kevin Smith wrote:
For what it's worth, I wrote the original PEP 318. I probably wasn't
qualified, but I just wanted a nice simple way to declare class methods
without having to repeat the function name. After submitting it to BDFL
for approval, more work was needed and the discussion of PEP 318 on
python-dev increased rapidly. It was evident that I was in over my head,
so I asked more someone more experienced to take over.

I guess others had bigger plans for my proposal that I had planned. It
has turned into the "solution" to many problems: type checking (both
arguments and returned values), metaclasses, metadata, interfaces,
function attributes, etc.). Unfortunately, in the process, this simple
request for syntactical sugar has turned into a monstrosity. In my
opinion, none of the proposed syntaxes really seem Pythonic. This PEP
just seems to be trying to solve too many problems.

Bear with me, but I'd like to propose one more syntax that is simple,
easy for newbies to understand, and nowhere near as powerful as the
current PEP's syntax. However, it doesn't add incoherent, arbitrary
syntax either.

def classmethod foo(x, y, z):
pass

That's it. One "decorator" that is a callable object that takes a
method as it's only argument. No expressions, lists, tuples, etc. Just
one callable object. Ok, if you absolutely must have more than one.

def classmethod synchronized foo(x, y, z):
pass

Once again, no expressions. I know that this isn't going to solve
everyone's type-checking, metadata, and function attribute problems, but
let's face it, using this PEP for all of those things just creates ugly
syntax. There must be more Pythonic ways to do those things in their
own PEPs.


Nope. That's using static declarations. We're a dynamically typed
language as much as possible. Isn't there something that doesn't
require any additional grammar words to identify classmethods and
staticmethods? Isn't there something, inherent in the way static,
class, and instance methods 'look' naturally, that would tell us what
they are?

Jul 18 '05 #2

P: n/a
Paul Morrow wrote:
Kevin Smith wrote:
def classmethod foo(x, y, z):
pass

That's it. One "decorator" that is a callable object that takes a
method as it's only argument. No expressions, lists, tuples, etc.
Just one callable object.


Nope. That's using static declarations. We're a dynamically typed
language as much as possible. Isn't there something that doesn't
require any additional grammar words to identify classmethods and
staticmethods?


It looks to me as though Kevin is not suggesting keywords, but
callables. In other words he would consider this valid, provided
my_own_decorator was a callable.

def my_own_decorator foo(x, y, z):
pass
-Peter
Jul 18 '05 #3

P: n/a
Peter Hansen wrote:
Paul Morrow wrote:
Kevin Smith wrote:
def classmethod foo(x, y, z):
pass

That's it. One "decorator" that is a callable object that takes a
method as it's only argument. No expressions, lists, tuples, etc.
Just one callable object.

Nope. That's using static declarations. We're a dynamically typed
language as much as possible. Isn't there something that doesn't
require any additional grammar words to identify classmethods and
staticmethods?

It looks to me as though Kevin is not suggesting keywords, but
callables. In other words he would consider this valid, provided
my_own_decorator was a callable.

def my_own_decorator foo(x, y, z):
pass
-Peter


Oh, sorry, I wasn't reading that closely enough. Hmmmm... it's an
interesting idea. It's not ugly...

First though, I still believe that we should exploit existing
conventions (recommended coding practices) as a way of getting 'free'
declarations for class, static, and instance methods (e.g. methods whose
first param is 'self' are instance methods, etc.). That feels very
pythonic to me, just as we use naming conventions to distinguish public,
private, and semi-private methods.

But I think that, where we want to provide additional info about a
method, and there are no conventions to take advantage of, Kevin's
suggestion does have some appeal.

Questions (for Kevin):

1. Would

def deco1 foo(a, b, c): pass

be the same as (just syntactic sugar for)

def foo(a, b, c): pass
foo = deco1(foo)

or would it mean something else?

2. Would

def deco1 deco2 foo(a, b, c): pass

be the same as

def foo(a, b, c): pass
foo = deco1(deco2(foo))

or

def foo(a, b, c): pass
foo = deco2(deco1(foo))
3. Would there be any restrictions on what a decorator could *do* to the
method it was passed? e.g. Could it change:

* the method's name (which could of course affect the method's
visibility: public|private|semi-private)?
* whether the method was a static, class, or instance method?
* the method's signature (formal parameter names, parameter order,
defaults values)?
Jul 18 '05 #4

P: n/a
In article <20********************@braeburn.themorgue.org>,
Kevin Smith <Ke*********@sas.com> wrote:

Bear with me, but I'd like to propose one more syntax that is simple,
easy for newbies to understand, and nowhere near as powerful as the
current PEP's syntax. However, it doesn't add incoherent, arbitrary
syntax either.

def classmethod foo(x, y, z):
pass

That's it. One "decorator" that is a callable object that takes a
method as it's only argument. No expressions, lists, tuples, etc. Just
one callable object. Ok, if you absolutely must have more than one.

def classmethod synchronized foo(x, y, z):
pass

Once again, no expressions. I know that this isn't going to solve
everyone's type-checking, metadata, and function attribute problems, but
let's face it, using this PEP for all of those things just creates ugly
syntax. There must be more Pythonic ways to do those things in their
own PEPs.


Kevin,

+1 for this idea.

I completely agree that the original PEP-318 proposed a simple and
reasonable idea, and I too have been much dismayed by all that seems to
have been grafted onto it since. This latest idea of yours certainly
sounds a lot more reasonable than anything else I've seen so far. It
solves the original well-defined problem cleanly, and probably solves
some of the other proposed uses too.

I would even go so far as to say: Go ahead and restrict it to at most
one callable object. If someone really wants to define a flaming hot
crossed synchronized blue classmethod foo, they can bloody well define a
callable object that has the (in)appropriate behaviour.

I hope that perhaps cooler heads (such as yours) will prevail, and keep
Python's syntax and semantics relatively neat and tidy. We don't need
the One PEP to Rule Them All, in the Land of Python where the shadows --
so far -- do not lie.

-M, "one more PEP out of you, mister, and you're history!" ;)

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #5

P: n/a
Michael J. Fromberger wrote:
In article <20********************@braeburn.themorgue.org>,
Kevin Smith <Ke*********@sas.com> wrote:
Bear with me, but I'd like to propose one more syntax that is simple,
easy for newbies to understand, and nowhere near as powerful as the
current PEP's syntax. However, it doesn't add incoherent, arbitrary
syntax either.

def classmethod foo(x, y, z):
pass

That's it. One "decorator" that is a callable object that takes a
method as it's only argument. No expressions, lists, tuples, etc. Just
one callable object. Ok, if you absolutely must have more than one.

def classmethod synchronized foo(x, y, z):
pass

Once again, no expressions. I know that this isn't going to solve
everyone's type-checking, metadata, and function attribute problems, but
let's face it, using this PEP for all of those things just creates ugly
syntax. There must be more Pythonic ways to do those things in their
own PEPs.

Kevin,

+1 for this idea.


I posted the same thing to python-dev (although it took a week for the
post to appear) and some guy said -infinity or something smart like that.
I think it is simpler to use keywords for classmethod and staticmethod
at least. Those are builtin features of python, just like they are
builtins for java (which has keywords for its builtins like static,
abstract, interface, etc.).
I propose this *in addition* to whatever decorator syntax we add. We
shouldn't consider staticmethod and classmethod as decorators.
Jul 18 '05 #6

P: n/a
Kevin Smith wrote:
For what it's worth, I wrote the original PEP 318. I probably wasn't
qualified, but I just wanted a nice simple way to declare class methods
without having to repeat the function name. After submitting it to BDFL
for approval, more work was needed and the discussion of PEP 318 on
python-dev increased rapidly. It was evident that I was in over my head,
so I asked more someone more experienced to take over.

I guess others had bigger plans for my proposal that I had planned. It
has turned into the "solution" to many problems: type checking (both
arguments and returned values), metaclasses, metadata, interfaces,
function attributes, etc.). Unfortunately, in the process, this simple
request for syntactical sugar has turned into a monstrosity. In my
opinion, none of the proposed syntaxes really seem Pythonic. This PEP
just seems to be trying to solve too many problems.

Bear with me, but I'd like to propose one more syntax that is simple,
easy for newbies to understand, and nowhere near as powerful as the
current PEP's syntax. However, it doesn't add incoherent, arbitrary
syntax either.

def classmethod foo(x, y, z):
pass

That's it. One "decorator" that is a callable object that takes a
method as it's only argument. No expressions, lists, tuples, etc. Just
one callable object.
+2 for me.

Ok, if you absolutely must have more than one.
def classmethod synchronized foo(x, y, z):
pass


No. If you want more than one, provide your own decorator, ie :

def synchronizedClassmethod(method):
return synchronized(classmethod(method))

def synchronizedClassmethod foo(x, y, z):
pass

My 2 eurocents
Bruno

Jul 18 '05 #7

P: n/a
On Tue, 17 Aug 2004 21:13:47 -0400,
Paul Morrow <pm****@yahoo.com> wrote:
First though, I still believe that we should exploit existing
conventions (recommended coding practices) as a way of getting 'free'
declarations for class, static, and instance methods (e.g. methods
whose first param is 'self' are instance methods, etc.). That feels
very pythonic to me, just as we use naming conventions to distinguish
public, private, and semi-private methods.


I don't understand how assigning semantic significance to a "recommended
coding practice" is Pythonic.

In the face of ambiguity, refuse to guess.

Explicit is better than implicit.

I think that the idea that started this thread is just right:

def decorator function( arguments ): pass

is exactly equivalent to

def function( arguments ): pass
decorator( function )

Note that:

- the decorator is right next to the function name
- the decorator is outside the code of the function
- there are no new keywords or punctuation
- it's dynamic, flexible, and extensible

It's also abusable, but that's the nature of a language as dynamic as
Python.

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
Never play leapfrog with a unicorn.
Jul 18 '05 #8

P: n/a
Dan Sommers wrote:
On Tue, 17 Aug 2004 21:13:47 -0400,
Paul Morrow <pm****@yahoo.com> wrote:

First though, I still believe that we should exploit existing
conventions (recommended coding practices) as a way of getting 'free'
declarations for class, static, and instance methods (e.g. methods
whose first param is 'self' are instance methods, etc.). That feels
very pythonic to me, just as we use naming conventions to distinguish
public, private, and semi-private methods.

I don't understand how assigning semantic significance to a "recommended
coding practice" is Pythonic.

In the face of ambiguity, refuse to guess.

Explicit is better than implicit.


Good conventions prevent ambiguity.

class Foo:
def method1(self, a, b): pass # clearly an instance method
def method2(cls, a, b): pass # clearly a class method
def method3(a, b): pass # clearly a static method
When declarations conflict with conventions, it makes us wonder what the
author really intended.

def staticmethod setX(self, x):
self.x = x

I think that the idea that started this thread is just right:


You're right, this thread is about decorators, not about more
opportunities for dynamic typing. I just wanted to remind us that
decorators are a lot like static typing, which isn't terribly pythonic.

Jul 18 '05 #9

P: n/a
In <ma**************************************@python.o rg> Paul Morrow
wrote:
Peter Hansen wrote:
Questions (for Kevin):
1. Would

def deco1 foo(a, b, c): pass

be the same as (just syntactic sugar for)

def foo(a, b, c): pass
foo = deco1(foo)

or would it mean something else?


Sorry, I guess I should have put the equivalent current Python code in
my first post. The example above is exactly what I meant.

2. Would

def deco1 deco2 foo(a, b, c): pass

be the same as

def foo(a, b, c): pass
foo = deco1(deco2(foo))

or

def foo(a, b, c): pass
foo = deco2(deco1(foo))
I would choose the first option since it's easier to transform the
string "deco1 deco2 foo" to "deco1(deco2(foo))" while I'm reading it (i.
e. it fits my head :) ).

3. Would there be any restrictions on what a decorator could *do* to
the method it was passed? e.g. Could it change:

* the method's name (which could of course affect the method's
visibility: public|private|semi-private)?
Nope, beginners wouldn't understand it immediately. That's just too
magical.
* whether the method was a static, class, or instance method?
Yes.
* the method's signature (formal parameter names, parameter order,
defaults values)?


I guess, in theory, it could since the object returned by the
"decorator" (I really hate that term) could return a completely
different object, but I wouldn't suggest it.

--
Kevin Smith
Ke*********@sas.com
Jul 18 '05 #10

P: n/a
In article <ma**************************************@python.o rg>,
Paul Morrow <pm****@yahoo.com> wrote:
Dan Sommers wrote:
I don't understand how assigning semantic significance to a
"recommended coding practice" is Pythonic.

In the face of ambiguity, refuse to guess.

Explicit is better than implicit.
Good conventions prevent ambiguity.

class Foo:
def method1(self, a, b): pass # clearly an instance method
def method2(cls, a, b): pass # clearly a class method
def method3(a, b): pass # clearly a static method


I think this is a terrible idea. What you are proposing is essentially
that Python should assign special meaning to the identifiers "self" and
"cls" when they appear as the first variable in a method definition
inside a class. I am having a hard time thinking of anything LESS in
the spirit of Python, short of writing in unstructured BASIC.

Good conventions do not prevent ambiguity, they merely help alleviate
its effects. And a "convention" that is enforced by the translator is
no longer a convention, but a rule of the language.
When declarations conflict with conventions, it makes us wonder what the
author really intended.

def staticmethod setX(self, x):
self.x = x
I find this at least as easy to understand as the current idiom:

def setX(self, x):
self.x = x
setX = staticmethod(setX)
You're right, this thread is about decorators, not about more
opportunities for dynamic typing.


Actually, as I read it, this thread is about getting back to the
original question PEP-318 was intended to answer, rather than all the
other cruft that the "decorators" idea has become laden with.

-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #11

P: n/a
On Wed, 18 Aug 2004 08:35:21 -0400,
Paul Morrow <pm****@yahoo.com> wrote:
Dan Sommers wrote:
In the face of ambiguity, refuse to guess.
Explicit is better than implicit. Good conventions prevent ambiguity. class Foo:
def method1(self, a, b): pass # clearly an instance method
def method2(cls, a, b): pass # clearly a class method
def method3(a, b): pass # clearly a static method
class Bar:
def method4( _, b ): pass # clearly a method
def method5( klass, b ): pass # clearly something else
def method6( uovo, b ): pass # clearly an Italian program(mer)
When declarations conflict with conventions, it makes us wonder what
the author really intended.
I agree completely. I have often noted that when a comment doesn't
match the code, they are *both* wrong.

If we wonder what the author intended, what should Python do?

I think that the idea that started this thread is just right:

You're right, this thread is about decorators, not about more
opportunities for dynamic typing. I just wanted to remind us that
decorators are a lot like static typing, which isn't terribly
pythonic.


I readily admit that my background is static typing: BASIC, FORTRAN,
assembly, C, etc.; my (arguably naïve) lisp and Python programs are
devoid of most of the dynamic typing I see here on c.l.p. OTOH, does
anyone want/need "dynamic decorators"? Is there a real use case for
code like this?

class C:
def m( self ): pass
m = decorate( m )

decorate = some_function
c1 = C( )

decorate = another_function
c2 = C( )

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
Never play leapfrog with a unicorn.
Jul 18 '05 #12

P: n/a
djw
Bruno Desthuilliers wrote:
Kevin Smith wrote:
For what it's worth, I wrote the original PEP 318. I probably wasn't
qualified, but I just wanted a nice simple way to declare class
methods without having to repeat the function name. After submitting
it to BDFL for approval, more work was needed and the discussion of
PEP 318 on python-dev increased rapidly. It was evident that I was in
over my head, so I asked more someone more experienced to take over.
I guess others had bigger plans for my proposal that I had planned.
It has turned into the "solution" to many problems: type checking
(both arguments and returned values), metaclasses, metadata,
interfaces, function attributes, etc.). Unfortunately, in the
process, this simple request for syntactical sugar has turned into a
monstrosity. In my opinion, none of the proposed syntaxes really seem
Pythonic. This PEP just seems to be trying to solve too many problems.

Bear with me, but I'd like to propose one more syntax that is simple,
easy for newbies to understand, and nowhere near as powerful as the
current PEP's syntax. However, it doesn't add incoherent, arbitrary
syntax either.

def classmethod foo(x, y, z):
pass

That's it. One "decorator" that is a callable object that takes a
method as it's only argument. No expressions, lists, tuples, etc.
Just one callable object.

+2 for me.

Ok, if you absolutely must have more than one.

> def classmethod synchronized foo(x, y, z):
> pass


No. If you want more than one, provide your own decorator, ie :

def synchronizedClassmethod(method):
return synchronized(classmethod(method))

def synchronizedClassmethod foo(x, y, z):
pass

My 2 eurocents
Bruno


+10
Jul 18 '05 #13

P: n/a
>>>>> "Kevin" == Kevin Smith <Ke*********@sas.com> writes:

Kevin> Bear with me, but I'd like to propose one more syntax that
Kevin> is simple, easy for newbies to understand, and nowhere near
Kevin> as powerful as the current PEP's syntax. However, it
Kevin> doesn't add incoherent, arbitrary syntax either.

Kevin> def classmethod foo(x, y, z):
Kevin> pass
Kevin> Once again, no expressions. I know that this isn't going
Kevin> to solve everyone's type-checking, metadata, and function
Kevin> attribute problems, but let's face it, using this PEP for
Kevin> all of those things just creates ugly syntax. There must
Kevin> be more Pythonic ways to do those things in their own PEPs.

Python is not anymore in the blissful stage of being able to
incorporate zillions of features that could be provided by a single
syntactic addition, and relatively comfortably as well. Long
decorators w/ arguments is where the decorator syntax is going to pay
off.

I don't even use static/classmethods, but I can imagine several
frameworks can use parametrized decorators to their advantage.

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #14

P: n/a
Michael J. Fromberger wrote:
In article <ma**************************************@python.o rg>,
Paul Morrow <pm****@yahoo.com> wrote:

Good conventions prevent ambiguity.

class Foo:
def method1(self, a, b): pass # clearly an instance method
def method2(cls, a, b): pass # clearly a class method
def method3(a, b): pass # clearly a static method

I think this is a terrible idea. What you are proposing is essentially
that Python should assign special meaning to the identifiers "self" and
"cls" when they appear as the first variable in a method definition
inside a class. I am having a hard time thinking of anything LESS in
the spirit of Python, short of writing in unstructured BASIC.


'self' already has a special meaning to experienced Python developers,
by virtue of its role in the recommended coding practices. And if you
ask experienced Python developers who understand the difference between
class, static, and instance methods, to guess what kind of method this is...

def foo(cls, a, b): pass

....I bet the majority would correctly guess "class". So these words
already do have special significance to *us* when used in the first
parameter position. Why not make them significant to the Python system too?

Good conventions do not prevent ambiguity, they merely help alleviate
its effects.
Maybe the problem is with the word 'ambiguity'. How about adherence to
good coding conventions can keep things from being interpreted in
multiple ways.

And a "convention" that is enforced by the translator is
no longer a convention, but a rule of the language.
Right. So a convention becomes a rule. Sounds like a natural evolution.
When declarations conflict with conventions, it makes us wonder what the
author really intended.

def staticmethod setX(self, x):
self.x = x

I find this at least as easy to understand as the current idiom:

def setX(self, x):
self.x = x
setX = staticmethod(setX)


Me too, but they both have problems. The staticmethod declaration is in
conflict with the use of 'self' as the first parameter. And they both
require more code than necessary. Just as it would be unecessary to say...

def private __foo(self): pass

Declarations aren't needed when an obvious interpretation of the code
conveys the desired meaning.

Jul 18 '05 #15

P: n/a
On Wed, 18 Aug 2004 08:35:21 -0400, Paul Morrow <pm****@yahoo.com> wrote:
Dan Sommers wrote:
On Tue, 17 Aug 2004 21:13:47 -0400,
Paul Morrow <pm****@yahoo.com> wrote:

First though, I still believe that we should exploit existing
conventions (recommended coding practices) as a way of getting 'free'
declarations for class, static, and instance methods (e.g. methods
whose first param is 'self' are instance methods, etc.). That feels
very pythonic to me, just as we use naming conventions to distinguish
public, private, and semi-private methods.

I don't understand how assigning semantic significance to a "recommended
coding practice" is Pythonic.

In the face of ambiguity, refuse to guess.

Explicit is better than implicit.


Good conventions prevent ambiguity.

Conventions don't direct computation though, they just direct human interpretation.
That is, unless you use convention-patterns as you propose for self etc., and then
they aren't just conventions. (As you may infer, my second thoughts on this are
not supportive of overloading naming. I thought it was not that "fragile" in the
narrow context of ordinary method definition, but I think it's a step on a slippery
slope to name-tricks that too many clever people may be tempted to step onto ;-)

class Foo:
def method1(self, a, b): pass # clearly an instance method
def method2(cls, a, b): pass # clearly a class method
def method3(a, b): pass # clearly a static method def method4(*args): pass # clearly different ;-)

When declarations conflict with conventions, it makes us wonder what the
author really intended. Sure, that's natural. Depending on the author, you might look for something
interesting ;-)
def staticmethod setX(self, x):
self.x = x

I think that the idea that started this thread is just right:


You're right, this thread is about decorators, not about more
opportunities for dynamic typing. I just wanted to remind us that
decorators are a lot like static typing, which isn't terribly pythonic.

Maybe simple-name callables between the def and the function name
would cover most use cases, and you could let people do what they want
to set up the names. A single name could also be bound to a composition of
several things in a lambda or whatever, if handy for repetitive concise use.
import mydecorators
deco1 = mydecorators.deco1
deco2 = mydecorators.deco2factory('this', 'that', 'tother')
class Foo(object):
def staticmethod deco1 method1(x,y): pass
def deco2 method2(self): pass

A plain name series between def and arg list shouldn't be hard grammar-wise, IWT.
The idea is growing on me. It doesn't abuse naming itself.

Argh, must go ...

Regards,
Bengt Richter
Jul 18 '05 #16

P: n/a
In article <20********************@braeburn.themorgue.org>,
Kevin Smith <Ke*********@sas.com> wrote:

Bear with me, but I'd like to propose one more syntax that is simple,
easy for newbies to understand, and nowhere near as powerful as the
current PEP's syntax. However, it doesn't add incoherent, arbitrary
syntax either.

def classmethod foo(x, y, z):
pass


You can't do ``grep "def foo"``; therefore, Guido rejected this. (It's
a tiny bit more complicated than that, but that's the essence.)
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"To me vi is Zen. To use vi is to practice zen. Every command is a
koan. Profound to the user, unintelligible to the uninitiated. You
discover truth everytime you use it." --*****@lion.austin.ibm.com
Jul 18 '05 #17

P: n/a
In article <cf**********@panix3.panix.com>, aa**@pythoncraft.com (Aahz)
wrote:
In article <20********************@braeburn.themorgue.org>,
Kevin Smith <Ke*********@sas.com> wrote:

Bear with me, but I'd like to propose one more syntax that is simple,
easy for newbies to understand, and nowhere near as powerful as the
current PEP's syntax. However, it doesn't add incoherent, arbitrary
syntax either.

def classmethod foo(x, y, z):
pass


You can't do ``grep "def foo"``; therefore, Guido rejected this. (It's
a tiny bit more complicated than that, but that's the essence.)


I suppose that's understandable; but would it really be so much worse to
have to write:

egrep "def [_a-z0-9]* *foo"

or, even

grep "def" | grep "foo("

I respectfully submit that this, while it makes a certain amount of
sense, is probably not a very good design criterion for new syntactic
features.

-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #18

P: n/a
In article <ma**************************************@python.o rg>,
Paul Morrow <pm****@yahoo.com> wrote:
Michael J. Fromberger wrote:
In article <ma**************************************@python.o rg>,
Paul Morrow <pm****@yahoo.com> wrote:
class Foo:
def method1(self, a, b): pass # clearly an instance method
def method2(cls, a, b): pass # clearly a class method
def method3(a, b): pass # clearly a static method
I think this is a terrible idea. What you are proposing is essentially
that Python should assign special meaning to the identifiers "self" and
"cls" when they appear as the first variable in a method definition
inside a class. I am having a hard time thinking of anything LESS in
the spirit of Python, short of writing in unstructured BASIC.


'self' already has a special meaning to experienced Python developers,
by virtue of its role in the recommended coding practices.


That's true: And note, that its special meaning is interpreted not by
the Python translator, but by the Python programmer. It is my feeling
that it should remain thus.
And if you ask experienced Python developers who understand the
difference between class, static, and instance methods, to guess what
kind of method this is...

def foo(cls, a, b): pass

...I bet the majority would correctly guess "class".
Well, given just that definition, the guess would be incorrect. The
current release of Python would also require:

def foo(cls, a, b): pass # As defined above
foo = classmethod(foo)

Otherwise, it would be an instance method, not a class method. I hope
this illustrates why visual conventions are not always as obvious as
they seem, and should not be cast into the concrete of implementation.
Right. So a convention becomes a rule. Sounds like a natural
evolution.
And just like in natural evoluation, not all mutations are desirable. ;)
Declarations aren't needed when an obvious interpretation of the code
conveys the desired meaning.


What about when the obvious interpretation of the code does NOT convey
the desired meaning?

-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #19

P: n/a
Michael J. Fromberger wrote:
In article <ma**************************************@python.o rg>,
Paul Morrow <pm****@yahoo.com> wrote:

Michael J. Fromberger wrote:
And if you ask experienced Python developers who understand the
difference between class, static, and instance methods, to guess what
kind of method this is...

def foo(cls, a, b): pass

...I bet the majority would correctly guess "class".

Well, given just that definition, the guess would be incorrect. The
current release of Python would also require:

def foo(cls, a, b): pass # As defined above
foo = classmethod(foo)

Otherwise, it would be an instance method, not a class method. I hope
this illustrates why visual conventions are not always as obvious as
they seem, and should not be cast into the concrete of implementation.


Actually, it illustrates the importance of proof-reading a post before
posting it, which I didn't (sorry). I should've also stated that the
Python developers would be told that this is a special version of Python
that automatically determines the type (static|class|instance) of a
method. In that light, do you see how effective the visual convention
can be?
Declarations aren't needed when an obvious interpretation of the code
conveys the desired meaning.

What about when the obvious interpretation of the code does NOT convey
the desired meaning?


Then we have a bad convention. One that I would absolutely agree should
not be enforced by the system. But that's not the case here. I believe
that the obvious interpretation of code written with this convention
would consistently and reliably convey the authors intent:

* If method's first param is 'self', it's an instance method.
* If method's first param is 'cls' or 'klass', it's a class method.
* All other methods are static methods.

Jul 18 '05 #20

P: n/a
In article <ma**************************************@python.o rg>,
Paul Morrow <pm****@yahoo.com> wrote:
Michael J. Fromberger wrote:

def foo(cls, a, b): pass

...I bet the majority would correctly guess "class".
Well, given just that definition, the guess would be incorrect. The
current release of Python would also require:

def foo(cls, a, b): pass # As defined above
foo = classmethod(foo)


Actually, it illustrates the importance of proof-reading a post
before posting it, which I didn't (sorry).


Understood, no worries.
I should've also stated that the Python developers would be told that
this is a special version of Python that automatically determines the
type (static|class|instance) of a method. In that light, do you see
how effective the visual convention can be?
Oh, I see it just fine -- but I still disagree with the idea of
including any such implicit magic in the language.

In fact, I don't like some of the magic that is already there -- such
as, for instance, the automatic mangling of class members whose names
begin with a double underscore to get "private" semantics. But that, at
least, is easy to avoid, if one doesn't want to use it.
* If method's first param is 'self', it's an instance method.
* If method's first param is 'cls' or 'klass', it's a class method.
* All other methods are static methods.


Uck. -1 from me.

-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #21

P: n/a
Michael J. Fromberger wrote:

Oh, I see it just fine -- but I still disagree with the idea of
including any such implicit magic in the language.

In fact, I don't like some of the magic that is already there -- such
as, for instance, the automatic mangling of class members whose names
begin with a double underscore to get "private" semantics. But that, at
least, is easy to avoid, if one doesn't want to use it.


Unless of course you want a method to be private/semi-private. How do
you feel about the way we can create/manipulate lists and dictionaries
using special (magical) syntax? Why is that different (acceptable)?

x = [10, 20, 30]

is shorthand for what would be much more code in other languages. Is
that syntax ok but

def __iAmPrivate(): pass

isn't? Why?

Jul 18 '05 #22

P: n/a
On Thu, 19 Aug 2004 06:35:18 -0400, Paul Morrow <pm****@yahoo.com> wrote:
Unless of course you want a method to be private/semi-private. How do
you feel about the way we can create/manipulate lists and dictionaries
using special (magical) syntax? Why is that different (acceptable)?


Look, name-mangling is horrid, and I don't think anyone's defending it. But
at the same time, "name mangling is there" is not an argument for extending
the horror to a whole new level.

Name mangling only occurs when you create a method with two leading
underscores, and no trailing ones. Your proposal would hit _every_ _single_
'def'. It's nasty, it's unpythonic, and there's approximately _zero_ chance of
it ever going into the language. Having said that, it's perfectly feasible to do
it with a metaclass, and if you want to use it in your code, please, feel free.

Anthony
Jul 18 '05 #23

P: n/a
Anthony Baxter wrote:
On Thu, 19 Aug 2004 06:35:18 -0400, Paul Morrow <pm****@yahoo.com> wrote:
Unless of course you want a method to be private/semi-private. How do
you feel about the way we can create/manipulate lists and dictionaries
using special (magical) syntax? Why is that different (acceptable)?

Look, name-mangling is horrid, and I don't think anyone's defending it. But
at the same time, "name mangling is there" is not an argument for extending
the horror to a whole new level.

Name mangling only occurs when you create a method with two leading
underscores, and no trailing ones. Your proposal would hit _every_ _single_
'def'. It's nasty, it's unpythonic, and there's approximately _zero_ chance of
it ever going into the language. Having said that, it's perfectly feasible to do
it with a metaclass, and if you want to use it in your code, please, feel free.

Anthony


You didn't follow that one with a smiley either... :-)
Jul 18 '05 #24

P: n/a
Anthony Baxter wrote:
On Thu, 19 Aug 2004 06:35:18 -0400, Paul Morrow <pm****@yahoo.com> wrote:
Unless of course you want a method to be private/semi-private. How do
you feel about the way we can create/manipulate lists and dictionaries
using special (magical) syntax? Why is that different (acceptable)?

Look, name-mangling is horrid, and I don't think anyone's defending it. But
at the same time, "name mangling is there" is not an argument for extending
the horror to a whole new level.


I disagree. It's an effective name-hiding technique. Simple +
Effective = Good.

Name mangling only occurs when you create a method with two leading
underscores, and no trailing ones. Your proposal would hit _every_ _single_
'def'. It's nasty, it's unpythonic, and there's approximately _zero_ chance of
it ever going into the language. Having said that, it's perfectly feasible to do
it with a metaclass, and if you want to use it in your code, please, feel free.


It's not unpythonic, if by that you mean that it's unlike other python
formalisms. And it would *only* hit those defs that were attributes of
classes derived from a new Object (capital 'O') class.
Jul 18 '05 #25

P: n/a
Anthony Baxter wrote:
Look, name-mangling is horrid, and I don't think anyone's defending it. But
at the same time, "name mangling is there" is not an argument for extending
the horror to a whole new level.

Paul Morrow <pm****@yahoo.com> wrote: I disagree. It's an effective name-hiding technique. Simple +
Effective = Good.


I disagree with your disagreement :-)

I find a mix of text and puctuation difficult to read. Human brains
don't read letters, they read whole words. That's why, for example,
it's so easy to make a typo and not notice it. I find "word.word" easy
to parse, but "word.__word" much more difficult. I don't know if it's
the switching back and forth between letters and symbols, or the
juxtaposition of the two symbols down on the baseline (i.e. ".__") that
makes it hard to read.

This is true of the __name__ convention for internal names too, but
somehow I don't find that as bad. Maybe because it's symmetric? Maybe
because my brain recognizes the whole __name__ as a unit, with the
"name" part of it being what I really recognize?

Even worse is when mix them. Stuff like "__myPrivateFunc.__name__" is
total gibberish to me.

Oh my god, I just realized (Ob decorator comment here) that if we start
having people write private decorators, we'll have things like:

@__decorator

which really makes me barf.
Jul 18 '05 #26

P: n/a
In article <ma**************************************@python.o rg>,
Paul Morrow <pm****@yahoo.com> wrote:
Michael J. Fromberger wrote:

Oh, I see it just fine -- but I still disagree with the idea of
including any such implicit magic in the language.

In fact, I don't like some of the magic that is already there -- such
as, for instance, the automatic mangling of class members whose names
begin with a double underscore to get "private" semantics. But that, at
least, is easy to avoid, if one doesn't want to use it.


Unless of course you want a method to be private/semi-private. How do
you feel about the way we can create/manipulate lists and dictionaries
using special (magical) syntax? Why is that different (acceptable)?

x = [10, 20, 30]

is shorthand for what would be much more code in other languages. Is
that syntax ok but

def __iAmPrivate(): pass

isn't? Why?


I'm glad you asked this question -- you have highlighted an important
distinction we should all heed. In short: The special syntax for list
construction (to use your example) is "explicit magic" rather than
"implicit magic."

Use of a square-bracketed tuple for list construction is almost
completely orthogonal to other language features (modulo indexing), it
correlates well to other familiar notations for lists, and it improves
the readability of the code without obscuring anything. These are some
key hallmarks of good syntax.

By contrast, the special leading-double-underscore convention for class
members and the idea to identify instance, static, or class methods
based on the name of their first parameter, are not even a visibly
syntactic change. Each of these ideas specially overloads the single
most common programming-language operation -- interpretation of a
variable name -- under particular circumstances. This technique is (as
far as I know) nearly unprecedented in other languages, so it would be
surprising to most programmers. Furthermore, I think it makes code less
readable, by hiding important facts inside an implicit assumption about
the content of non-keyword identifiers, which are otherwise never
special.

Many people respond to this by saying, "The programmer has to be careful
anyway, so what is one more thing?" You could ask the same question
about drivers and beer. Little distractions add up to big mistakes.

Let me add that I do not intend to assert that all syntactic sugar is
bad (even if, as Alan Perlis suggested, "syntactic sugar causes cancer
of the semi-colon" :) However, the simple fact is, unless there is a
really good reason, we shouldn't make programmers (i.e., ourselves)
memorize more special cases. Going back to your example: There is an
excellent case for a compact and orthogonal list construction notation.
There is no good case for magically overloading non-keyword identifiers
in certain contexts -- especially when there is a better and more
explicit way to do it.

Thank you for your good example, Paul.

Cheers,
-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #27

P: n/a
"Kevin Smith" <Ke*********@sas.com> wrote in message
news:20********************@braeburn.themorgue.org ...
For what it's worth, I wrote the original PEP 318. I probably wasn't
qualified, but I just wanted a nice simple way to declare class methods
without having to repeat the function name. After submitting it to BDFL
for approval, more work was needed and the discussion of PEP 318 on
python-dev increased rapidly. It was evident that I was in over my head,
so I asked more someone more experienced to take over.

I guess others had bigger plans for my proposal that I had planned. It
has turned into the "solution" to many problems: type checking (both
arguments and returned values), metaclasses, metadata, interfaces,
function attributes, etc.). Unfortunately, in the process, this simple
request for syntactical sugar has turned into a monstrosity. In my
opinion, none of the proposed syntaxes really seem Pythonic. This PEP
just seems to be trying to solve too many problems.
I don't think that is the case. What is actually going on has to do
with the mechanics of the classmethod and staticmethod functions.
They wrap the actual function in a special purpose descriptor.

The current approach is simply to allow running any wrapping
function, not just classmethod and staticmethod. That is, in a
very real sense, realistic because if they put in a special purpose
hack for just those two descriptors, then you'd get a huge backlash
from people who will still complain that it doesn't support, for
example, properties.

All the other stuff you're seeing isn't something that the proposal
has to support explicitly. You can wrap a function in any kind
of a descriptor you want. They are simply use cases, and IMHO,
some of them are not very well founded. However, none of them
involves one line of code more or less than the basic "allow
any descriptor anyone cares to write as a wrapper" approach.

The arguement is, and always has been, about syntax. Everyone
agrees that the current situation is not ideal; putting the wrapping
assignment statement after the method is a very poor way of
declaring intent.

In other words, forget the use cases. They're irrelevant. The
sticking point on syntax has to be solved first. If it is, then
I doubt if you're going to get a special purpose, just those
two specific descriptors and no others, solution. I just don't
see it happening.

There is, by the way, one syntax that hasn't to my knowledge
been proposed that is straightforward, natural, doesn't
make it begin to look like line noise and is completely
consistent with existing syntax. Just use the '.' operator
on the name and be done with it. For example:

def classmethod.fubar(self, widget, wadget, boff):
pass

I'm not seriously proposing it because I'd like to reserve
that idea to be able to insert a method into an instance
or existing class without either having to do an extra
assignment, or having to pollute the module namespace
in passing.

John Roth

--
Kevin Smith
Ke*********@sas.com

Jul 18 '05 #28

P: n/a
On Thu, 19 Aug 2004 10:28:07 -0400, Roy Smith wrote:

Oh my god, I just realized (Ob decorator comment here) that if we start
having people write private decorators, we'll have things like:

@__decorator


I wish to have a private decorator. My apartment looks boring.

-m
Jul 18 '05 #29

P: n/a
On Thu, 19 Aug 2004 07:52:38 -0400, Paul Morrow <pm****@yahoo.com> wrote:
I wrote:
Look, name-mangling is horrid, and I don't think anyone's defending it. But
at the same time, "name mangling is there" is not an argument for extending
the horror to a whole new level.

Name mangling only occurs when you create a method with two leading
underscores, and no trailing ones. Your proposal would hit _every_ _single_
'def'. It's nasty, it's unpythonic, and there's approximately _zero_ chance of
it ever going into the language. Having said that, it's perfectly feasible to do
it with a metaclass, and if you want to use it in your code, please, feel free.


You didn't follow that one with a smiley either... :-)


That's because I wasn't joking, at all. Look, your idea is a _bad_ one. Numerous
people have pointed out why. Let it die.
Jul 18 '05 #30

P: n/a


Roy Smith wrote:
Anthony Baxter wrote:
Look, name-mangling is horrid, and I don't think anyone's defending it. But
at the same time, "name mangling is there" is not an argument for extending
the horror to a whole new level.


Paul Morrow <pm****@yahoo.com> wrote:
I disagree. It's an effective name-hiding technique. Simple +
Effective = Good.

I disagree with your disagreement :-)

I find a mix of text and puctuation difficult to read. Human brains
don't read letters, they read whole words. That's why, for example,
it's so easy to make a typo and not notice it. I find "word.word" easy
to parse, but "word.__word" much more difficult.


I agree, but see this as similar to the naming convention:
long_symbolic_representation at first glance,
this looks like
three names
why not:
longSymbolicRepresentation? this makes the oneness
clearer

Returning to the subject line - When will the final decision be handed
down?

My own preferences are: (1) transform or transformer not decorator
(2) the transforms should follow the thing
being
transformed. i.e. after the script has
declared the name.
(3) a list of transforms.
(4) the list should have one entry per line,
to make reading easier.

Colin W.
I don't know if it's the switching back and forth between letters and symbols, or the
juxtaposition of the two symbols down on the baseline (i.e. ".__") that
makes it hard to read.

This is true of the __name__ convention for internal names too, but
somehow I don't find that as bad. Maybe because it's symmetric? Maybe
because my brain recognizes the whole __name__ as a unit, with the
"name" part of it being what I really recognize?

Even worse is when mix them. Stuff like "__myPrivateFunc.__name__" is
total gibberish to me.

Oh my god, I just realized (Ob decorator comment here) that if we start
having people write private decorators, we'll have things like:

@__decorator

which really makes me barf.


Jul 18 '05 #31

P: n/a
In article <10*************@news.supernews.com>,
"John Roth" <ne********@jhrothjr.com> wrote:
"Kevin Smith" <Ke*********@sas.com> wrote in message
news:20********************@braeburn.themorgue.org ...
For what it's worth, I wrote the original PEP 318. [...]

In my opinion, none of the proposed syntaxes really seem Pythonic.
This PEP just seems to be trying to solve too many problems.
The arguement is, and always has been, about syntax. Everyone agrees
that the current situation is not ideal; putting the wrapping
assignment statement after the method is a very poor way of declaring
intent.


I agree that the current situation is not ideal. However, I would also
argue that many of the proposed replacements are even worse. Kevin
Smith's latest proposal (cf. <http://shorl.com/bykaprifitrevi>) is, in
my view, the most reasonable suggestion so far.
In other words, forget the use cases. They're irrelevant.


On this point, I strongly disagree. If you don't have a use case, there
is no point whatsoever in arguing about the syntax of a feature.

Now, if you want to argue about general syntactic design principles,
maybe that is an interesting topic -- but it is one level removed from
what PEP-318 is all about, and therefore (in my opinion) not really
germane to the present discussion.

-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #32

P: n/a
"Michael J. Fromberger" <Mi******************@Clothing.Dartmouth.EDU> wrote
in message news:Michael.J.Fromberger-D24476.14010119082004@localhost...
In article <10*************@news.supernews.com>,
"John Roth" <ne********@jhrothjr.com> wrote:
"Kevin Smith" <Ke*********@sas.com> wrote in message
news:20********************@braeburn.themorgue.org ...
For what it's worth, I wrote the original PEP 318. [...]

In my opinion, none of the proposed syntaxes really seem Pythonic.
This PEP just seems to be trying to solve too many problems.
The arguement is, and always has been, about syntax. Everyone agrees
that the current situation is not ideal; putting the wrapping
assignment statement after the method is a very poor way of declaring
intent.


I agree that the current situation is not ideal. However, I would also
argue that many of the proposed replacements are even worse. Kevin
Smith's latest proposal (cf. <http://shorl.com/bykaprifitrevi>) is, in
my view, the most reasonable suggestion so far.
In other words, forget the use cases. They're irrelevant.


On this point, I strongly disagree. If you don't have a use case, there
is no point whatsoever in arguing about the syntax of a feature.


There is a use case. If you go back and read the original
post I was replying to, it contains the sentence:

[begin quote]
I guess others had bigger plans for my proposal that I had planned. It
has turned into the "solution" to many problems: type checking (both
arguments and returned values), metaclasses, metadata, interfaces,
function attributes, etc.).
[end quote]

This is the context in which you should have taken my comment
to "forget the use cases." The original use case (classmethod
and staticmethod) is clearly still there, as my comments
in the post you reply to should have made clear.

John Roth
Now, if you want to argue about general syntactic design principles,
maybe that is an interesting topic -- but it is one level removed from
what PEP-318 is all about, and therefore (in my opinion) not really
germane to the present discussion.

-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA

Jul 18 '05 #33

P: n/a
In article <10*************@news.supernews.com>,
"John Roth" <ne********@jhrothjr.com> wrote:
"Michael J. Fromberger" <Mi******************@Clothing.Dartmouth.EDU> wrote
in message news:Michael.J.Fromberger-D24476.14010119082004@localhost...
In article <10*************@news.supernews.com>,
"John Roth" <ne********@jhrothjr.com> wrote:
In other words, forget the use cases. They're irrelevant.


On this point, I strongly disagree. If you don't have a use case, there
is no point whatsoever in arguing about the syntax of a feature.


There is a use case. If you go back and read the original
post I was replying to, it contains the sentence:

[begin quote]
I guess others had bigger plans for my proposal that I had planned. It
has turned into the "solution" to many problems: type checking (both
arguments and returned values), metaclasses, metadata, interfaces,
function attributes, etc.).
[end quote]


Ah, I see. I misunderstood your intent. My apologies.

Nevertheless, I think it's clear the Python community at large ought to
have a clearer idea of exactly what the use cases ARE (and, more
importantly, what they're not) before deciding on a syntax. It's not
clear to me that there's consensus on purpose yet (as witness the wildly
divergent ideas that have accumulated on the wiki, comp.lang.python, and
python-dev).

Cheers,
-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 18 '05 #34

P: n/a
Ville Vainio <vi***@spammers.com> wrote in message news:<du*************@lehtori.cc.tut.fi>...
>> "Kevin" == Kevin Smith <Ke*********@sas.com> writes:

Kevin> Bear with me, but I'd like to propose one more syntax that
Kevin> is simple, easy for newbies to understand, and nowhere near
Kevin> as powerful as the current PEP's syntax. However, it
Kevin> doesn't add incoherent, arbitrary syntax either.

Kevin> def classmethod foo(x, y, z):
Kevin> pass

I don't even use static/classmethods, but I can imagine several
frameworks can use parametrized decorators to their advantage.


Well, allow me to contribute my thoughts on staticmethod and classmethod:
I am barely starting out with Python and my class objects are already
loaded with so many

foo = staticmethod(foo)

statements. In other words these are very useful: they should be part of
Python's syntax. Other than the above proposal, which I think is the most
obvious thing that could be done, I would also like to contribute yet another
syntax:

class Foo:
# stuff
classmethods:
# classmethods here
staticmethods:
# staticmethods here

In the spirit of Python, this scheme would lead to even less typing
on average than would be required with Kevin's solution, although I
must admit that Kevin's solution was the very first thing that came
to mind when I was looking for classmethods/staticmethods.

staticmethods are very useful: you can pack related methods in a class
and use them as getters for class objects which need not be differentiated
among instances. It may even be, that due to python's class objects feature
the user never cares to instantiate certain types of classes anyways. For
instance, a class object with staticmethods can simply be used as a
singleton object: very convenient, if it were not for this ugly
staticmethod syntax. And you may ask, what are the advantages
of using staticmethod inside a class as opposed to using
plain methods? The answer to that question is polymorphism:
Imagine a hierarchy of singleton classes derived from a base
class with a common interface. The singleton class objects
can then be processed polymorphically. Class objects, unlike
class instances, are singletons by nature: what a convenient
means of using singletons pythons offers us!

class Person:
def name():
return "Sorry, I'm just an abstract class."
name = staticmethod(name)
def favoMovie():
return "Monty Python's Flying Circus"
favMovie = staticmethod(FavMovie)
def favFood():
return "SPAM!"
favFood = staticmethod(favFood)

class JoeDoe(Person):
def name():
return "Joe Doe"
name = staticmethod(name)

class JaneDoe(Person):
def name():
return "Jane Doe"
name = staticmethod(name)
def favFood():
return "Eggs"
favFood = staticmethod(FavFood)

The other alternative is to attach methods to instances of a common class
after they are created, which is also something that can be done in Python
but not in most other languages.

Note that the getters I have coded, in general may involve more complex
logic than shown here, so that we really do need methods and not palin
variables in such cases.

Overall, allow me to say that OO stuff seems to be much more flexible in an
interpreted environment such as Python than it is in compiled languages.

Feedback welcome,

Regards,

Neil
Jul 18 '05 #35

P: n/a
"Michael J. Fromberger" <Mi******************@Clothing.Dartmouth.EDU> wrote
in message news:Michael.J.Fromberger-AE7E18.17313219082004@localhost...
In article <10*************@news.supernews.com>,
"John Roth" <ne********@jhrothjr.com> wrote:
"Michael J. Fromberger" <Mi******************@Clothing.Dartmouth.EDU> wrote in message news:Michael.J.Fromberger-D24476.14010119082004@localhost...
In article <10*************@news.supernews.com>,
"John Roth" <ne********@jhrothjr.com> wrote:

> In other words, forget the use cases. They're irrelevant.

On this point, I strongly disagree. If you don't have a use case, there is no point whatsoever in arguing about the syntax of a feature.
There is a use case. If you go back and read the original
post I was replying to, it contains the sentence:

[begin quote]
I guess others had bigger plans for my proposal that I had planned. It
has turned into the "solution" to many problems: type checking (both
arguments and returned values), metaclasses, metadata, interfaces,
function attributes, etc.).
[end quote]


Ah, I see. I misunderstood your intent. My apologies.

Nevertheless, I think it's clear the Python community at large ought to
have a clearer idea of exactly what the use cases ARE (and, more
importantly, what they're not) before deciding on a syntax. It's not
clear to me that there's consensus on purpose yet (as witness the wildly
divergent ideas that have accumulated on the wiki, comp.lang.python, and
python-dev).


I don't think they're particularly related. Functionally, whatever happens
as the result of a decorator will be the return of an object which
will be bound to the class or module (or serve as the input to another
decorator, of course.) In most cases, this will either be the original input
or a descriptor that has the original input as an attribute.

This is a very generic mechanism of amazing simplicity. It can be put
to as many uses as one wishes. There are currently implementations
of just about everything that has been suggested, including Design
by Contract, Aspects and several forms of type checking.

The whole question of syntax is simply orthogonal. The current
syntax works perfectly well; it's just very poor from an intention revealing
standpoint.

John Roth
Cheers,
-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA

Jul 18 '05 #36

P: n/a
Anthony Baxter wrote:
On Thu, 19 Aug 2004 07:52:38 -0400, Paul Morrow <pm****@yahoo.com> wrote:
I wrote:
Look, name-mangling is horrid, and I don't think anyone's defending it. But
at the same time, "name mangling is there" is not an argument for extending
the horror to a whole new level.

Name mangling only occurs when you create a method with two leading
underscores, and no trailing ones. Your proposal would hit _every_ _single_
'def'. It's nasty, it's unpythonic, and there's approximately _zero_ chance of
it ever going into the language. Having said that, it's perfectly feasible to do
it with a metaclass, and if you want to use it in your code, please, feel free.


You didn't follow that one with a smiley either... :-)

That's because I wasn't joking, at all. Look, your idea is a _bad_ one. Numerous
people have pointed out why. Let it die.


I know you weren't Anthony (that was a joke). I understand that you
don't like this idea, but that doesn't make it a _bad_ one. Numerous
people have *not* effectively pointed out the problems with it (and
neither have you, sir).

Don't use it, if you don't want to. Make your code as hard to
understand as you like. Python gives you that freedom.
Jul 18 '05 #37

P: n/a
On Fri, 20 Aug 2004 05:57:42 -0400, Paul Morrow <pm****@yahoo.com> wrote:
I know you weren't Anthony (that was a joke). I understand that you
don't like this idea, but that doesn't make it a _bad_ one. Numerous
people have *not* effectively pointed out the problems with it (and
neither have you, sir).


Err, what? Have you bothered to read the replies I sent to you? This
is _bad_ magic behaviour. Python does not care about argument lists
now, and adding this is icky. Your behaviour when _adding_ methods
to classes is extremely undefined, particularly in the presence of
descriptors. Explaining this to new users would be complex. It's a
messy interference in the way Python's OO builds classes and objects,
which is currently very clear and easy to follow[1]. It's not explicit, but
implicit. How many ways do I have to spell this out?

[1] with the double-underscore mangling put to one side, or preferably,
off a bridge.

The only argument _for_ this that you've offered is that it's just like the
double-underscores. This is a losing argument (with me, anyway) as
I regard the double-underscore mangling as awful - that sort of "data
hiding" just ends up being a pain in the arse when you want to poke
with a class's internals. Python regards everyone as an adult in that
respect, unlike the "protecting you from yourself" C++ nightmare. In
addition, the double-underscore is just random magic that occurs when
a class is created, not subsequently:
class A: .... __foo = 1
.... dir(A) ['_A__foo', '__doc__', '__module__'] A.__bar = 2
dir(A)

['_A__foo', '__bar', '__doc__', '__module__']

for the same reasons, your idea would lead to inconsistencies.

Anthony
Jul 18 '05 #38

P: n/a
Anthony Baxter wrote:
On Fri, 20 Aug 2004 05:57:42 -0400, Paul Morrow <pm****@yahoo.com> wrote:
I know you weren't Anthony (that was a joke). I understand that you
don't like this idea, but that doesn't make it a _bad_ one. Numerous
people have *not* effectively pointed out the problems with it (and
neither have you, sir).

Err, what? Have you bothered to read the replies I sent to you?


Yes of course I have. You can tell because I've replied to everything
you've said, directly (as best I could) addressing your 'points'. Have
you noticed my replies? Did you bother to read them?
This is _bad_ magic behaviour. Python does not care about argument lists
now, and adding this is icky.
Python doesn't do this now. Check. You think that it's "icky". Check.
Your behaviour when _adding_ methods to classes is extremely undefined,
particularly in the presence of
descriptors.
If you're talking about dynamically adding methods to classes (at
runtime), we've discussed this in general. You have to have the first
parm name correct before you add the method.

But we haven't talked about descriptor issues yet, have we? What's the
problem with them?
Explaining this to new users would be complex.
We discussed this before too (didn't we?). It will be *less* complex
for new users. Well, you tell me. Here's the only part of the
classmethod documentation that would change (from
http://docs.python.org/lib/built-in-funcs.html)...

"""
A class method receives the class as implicit first argument, just like
an instance method receives the instance. To declare a class method, use
this idiom:

class C:
def f(cls, arg1, arg2, ...): ...
f = classmethod(f)
"""

....it would be changed to (something like) this...

"""
A class method receives the class as its first argument 'cls', just like
an instance method receives the instance as its first argument 'self'.
To declare a class method, use this idiom:

class C:
def f(cls, arg1, arg2, ...): ...

Note that the first argument of each class method must be named 'cls'.
"""

It's a
messy interference in the way Python's OO builds classes and objects,
which is currently very clear and easy to follow[1].
We haven't discussed this, have we? What do you mean?

It's not explicit, but implicit.
True. But then so is dynamic typing, a powerful feature of Python that
differentiates it from languages like Java, C++. Therefore, you aren't
saying enough here for that point to be valid.

How many ways do I have to spell this out?
One valid spelling would be a good start.


The only argument _for_ this that you've offered is that it's just like the
double-underscores.
Oh my... <sigh> Have you been reading *my* posts? If so, I must be
doing a terrible job of communicating here (my apologies). Here are
four reasons in favor of it. Rip them apart to your satisfaction.

1. It make formal a convention widely used by others and therefore would
have an obvious interpretation to readers of your code.

2. It doesn't require as much typing as the current technique nor any
proposed decorator technique.

3. It is less error prone (because it is WYSIWYG) than the current
technique.

4. It is easier to understand than the current technique.

double-underscores. This is a losing argument (with me, anyway) as
I regard the double-underscore mangling as awful - that sort of "data
hiding" just ends up being a pain in the arse when you want to poke
with a class's internals. Python regards everyone as an adult in that
respect, unlike the "protecting you from yourself" C++ nightmare. In
addition, the double-underscore is just random magic that occurs when
a class is created, not subsequently:

class A:
... __foo = 1
...
dir(A)
['_A__foo', '__doc__', '__module__']
A.__bar = 2
dir(A)


['_A__foo', '__bar', '__doc__', '__module__']

for the same reasons, your idea would lead to inconsistencies.


That's an interesting point. The behavior you illustrate is apparently
a Python bug wrt private attributes. If it was consistent...

A.__bar = 2

would work, but a subsequent

print A.__bar

would generate an attribute error.

But of course its easy to make Python work that way (as I show below).
Likewise, I'm sure similar inconsistencies in 'my' (for lack of a better
word --- I didn't actually come up with it) idea could be as easily
resolved.

################################################## ###########
class M(type):
def __setattr__(metacls, attrName, value):
if attrName.startswith('__'):
attrName = '_%s%s' % (metacls.__name__, attrName)
type.__setattr__(metacls, attrName, value)

class A:
__metaclass__ = M
__foo = 1

print [x for x in dir(A) if x.startswith('_A')] # 1.
A.__bar = 2
print [x for x in dir(A) if x.startswith('_A')] # 2.

"""Footnotes:
1. prints ['_A__foo']
2. prints ['_A__bar', '_A__foo']
"""
################################################## ###########
Jul 18 '05 #39

This discussion thread is closed

Replies have been disabled for this discussion.