Attack a sacred Python Cow

N

Nikolaus Rath

Terry Reedy said:
class C():
def f():
a = 3

Inserting self into the arg list is trivial. Mindlessly deciding
correctly whether or not to insert 'self.' before 'a' is impossible
when 'a' could ambiguously be either an attribute of self or a local
variable of f. Or do you and/or Jordan plan to abolish local
variables for methods?

Why do you think that 'self' should be inserted anywhere except in the
arg list? AFAIU, the idea is to remove the need to write 'self' in the
arg list, not to get rid of it entirely.


Best,

-Nikolaus

--
»It is not worth an intelligent man's time to be in the majority.
By definition, there are already enough people to do that.«
-J.H. Hardy

PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C
 
C

cokofreedom

By that logic, C++ is not OO. By that logic, Ruby is not OO. By that
logic, I know of only one OO language: Java :)

The fact that a language doesn't force you to do object-oriented
programming doesn't mean that it's not object-oriented. In other
words, your words are nonsense.

No, what it means is that it might support OO but doesn't have to, it
isn't the only way to code.

Supporting and Being OO are very different.
 
S

s0suk3

No, what it means is that it might support OO but doesn't have to, it
isn't the only way to code.

"Support OO but it doesn't have to"? That sounds like saying that in
some Python implementations you'll be able to use OO, but that you
just might bump into a Python distribution where you would type

class MClass:
pass

at the interpreter and it would give you an syntax error. Is that what
you mean?
Supporting and Being OO are very different.

I guess at this point it's rather pointless to discuss this because of
the different and deep level of interpretation that we might have on
the words "support" and "be." IMO, the obvious thing to say is that a
language that *supports* OO can also be said to *be* OO. However, it
would seem just ridiculous to me to say the same thing about a
language like, e.g., Perl, where OO is so pathetic. But maybe this is
just a game of words...

I consider Python to *be* OO, anyway.

Sebastian
 
L

Lie

In reality? I'll just keep writing Python (hopefully enough so that
explicit self become burned into muscle memory), and use other
languages when necessary (no more C than I have to, looking forward to
dabbling in Erlang soon, and one day overcoming the parentheses phobia
enough to really tackle Lisp properly). When I'm old enough and wise
enough, and have the time, energy and inclination, maybe I'll sit down
and put a proper effort into designing and implementing a new language
that bests suits my own particular style and needs.
Just maybe it'll
be good enough that smart people will rally to defend its design
principles from people attacking them on the internet :)

Forgive me in advance, but that is just a day dream, however good a
language design is, there WILL be other people who disagree with the
corner cases. Python is one example, even with Guido that is great at
designing language, there are many edges in python that many people
disagree and attack from time to time, but not every one of those
edges got fixed, why? Because it is impossible to appeal everyone, if
the language is changed according to your (or other's) idea, there
will be some other people who don't like it (with your examples, it
might be the people who are used to functional programming and people
who want to implement a very complex behavior in __eq__ and __ne__).
What seemed to be the obviously correct behavior for you would be
unexpected for some other people (this is also in python's Zen
although in a slightly twisted kind of way[1]: "There should be one--
and preferably only one --obvious way to do it; Although that way may
not be obvious at first unless you're Dutch.").

[1] Basically, the Zen is saying that whether and idea is the
obviously correct way to do something is measured by Guido's measuring
tape. Basically it's also saying that python is designed according to
what HE thinks is obviously correct.

The Zen you're attacking: "Explicit is better than implicit," is a
generally good advice, although as you mentioned, it doesn't fit every
single cases in the world, which leads us to the other Zen[2]:
"Special cases aren't special enough to break the rules; Although
practicality beats purity."

[2] In our case, "Explicit is better than implicit" is the "rules",
the corner cases where implicit is a generally better choice is the
"special cases". The first verse ("Special cases ... break rules")
implies that everything should be explicit, no exceptions, while the
second verse ("practicality beats purity") means that if something
breaking the rule makes it more practical, then you don't have to
follow the rules[3]. These two statements contradicts each other,
implying an implicit Zen: "Foolish consistency is the hobgoblin's
little minds", it is OK to break the rules sometimes.

[3] Despite saying this, I also have to emphasize that what is
practical or not is measured by Guido's tape.

With this explained, I hope you understand the point I'm making:
"There is no The Perfect Language, that is liked by everyone in the
world." The moral is, if you like a language, try to resist its warts
and know that each wart have its own story. You don't have to like the
warts, but you just need to stand to it.
 
A

alex23

These two statements contradicts each other,
implying an implicit Zen: "Foolish consistency is the hobgoblin's
little minds", it is OK to break the rules sometimes.

"A foolish consistency is _the_ hobgoblin of little minds." (Ralph
Waldo Emerson, although the emphasis is mine)

I do like your version, though :)
 
T

Terry Reedy

Kay said:
This isn't the problem Jordan tries to address. It's really just about
`self` in the argument signature of f, not about its omission in the
body.

That is not at all how I read him, so I will let him respond if he
wishes. The main problem moving a function from module scope to class
scope is prefixing the proper variables. Adding a param name, whether
'self', 's', 'this', or whatever, is trivial and hardly worth the ink.
 
T

Terry Reedy

Nikolaus said:
Why do you think that 'self' should be inserted anywhere except in the
arg list? AFAIU, the idea is to remove the need to write 'self' in the
arg list, not to get rid of it entirely.

Because you must prefix self attributes with 'self.'. If you do not use
any attributes of the instance of the class you are making the function
an instance method of, then it is not really an instance method and need
not and I would say should not be masqueraded as one. If the function
is a static method, then it should be labeled as one and no 'self' is
not needed and auto insertion would be a mistake. In brief, I assume
the OP wants 'self' inserted in the body because inserting it only in
the parameter list and never using it in the body is either silly or wrong.

tjr
 
F

Fuzzyman

Hi everyone,

I'm a big Python fan who used to be involved semi regularly in
comp.lang.python (lots of lurking, occasional posting) but kind of
trailed off a bit. I just wrote a frustration inspired rant on my
blog, and I thought it was relevant enough as a wider issue to the
Python community to post here for your discussion and consideration.

This is not flamebait. I love Python, and I'm not out to antagonise
the community. I also realise that one of the issues I raise is way
too ingrained to be changed now. I'd just like to share my thinking on
a misstep in Python's guiding principles that has done more harm than
good IMO. So anyway, here's the post.

I've become utterly convinced that at least one criticism leveled at
my favourite overall programming language, Python, is utterly true and
fair. After quite a while away from writing Python code, I started
last night on a whim to knock up some code for a prototype of an idea
I once had. It's going swimmingly; the Python Image Library, which I'd
never used before, seems quick, intuitive, and with the all the
features I need for this project. As for Python itself, well, my heart
still belongs to whitespace delimitation. All the basics of Python
coding are there in my mind like I never stopped using them, or like
I've been programming in this language for 10 years.

Except when it comes to Classes. I added some classes to code that had
previously just been functions, and you know what I did - or rather,
forgot to do? Put in the 'self'. In front of some of the variable
accesses, but more noticably, at the start of *every single method
argument list.* This cannot be any longer blamed as a hangover from
Java - I've written a ton more code, more recently in Python than in
Java or any other OO language. What's more, every time I go back to
Python after a break of more than about a week or so, I start making
this 'mistake' again. The perennial justification for this 'feature'
of the language? That old Python favourite, "Explicit is better than
implicit."


It's damn useful for scoping. You can look in the body of your method
and tell whether you are accessing local variables or instance
variables.

I'm a great fan of self and I'm afraid you're flogging a dead horse on
that one.

Your point about rich comparison (at least the == != problem) is fair..
This one is fixed in Python 3 though I believe.

Michael Foord
 
P

Paul Boddie

That is not at all how I read him, so I will let him respond if he
wishes. The main problem moving a function from module scope to class
scope is prefixing the proper variables. Adding a param name, whether
'self', 's', 'this', or whatever, is trivial and hardly worth the ink.

He wrote the following of relevance:

"I added some classes to code that had previously just been functions,
and you know what I did - or rather, forgot to do? Put in the 'self'.
In front of some of the variable accesses, but more noticably, at the
start of *every single method argument list.*"

And rounding off with this on the subject:

"The problem is that the explicit requirement to have self at the
start
of every method is something that should be shipped off to the
implicit category."

I guess the desire is to have Java-like behaviour: when defining a
method, which must typically be done in the class definition in Java
(unless they've enhanced that area in the past few years), you never
write a "this" parameter in the method signature, but you are free to
qualify instance attribute accesses with "this". Personally, I liked
the Modula-3-inspired requirement for "self" in Python, but I can see
how a reminder of what it is in every method signature (defined within
a class) might be regarded as overly explicit.

Paul
 
C

Colin J. Williams

Fuzzyman said:
It's damn useful for scoping. You can look in the body of your method
and tell whether you are accessing local variables or instance
variables.

I'm a great fan of self and I'm afraid you're flogging a dead horse on
that one.

Your point about rich comparison (at least the == != problem) is fair..
This one is fixed in Python 3 though I believe.

Michael Foord

I hope that the OP will develop some
specific proposal, narrowly focused on
the "self" issue.

It has always seemed redundant on the
argument line of a definition. It does
permit one to use some other word but is
that of any real value.

One can still use self.a= 'z' or perhaps
..a= 'z'.

Colin W.
 
J

Jordan

Well this discussion is chugging along merrily now under its own
steam, but as the OP I should probably clarify a few things about my
own views since people continue to respond to them (and are in some
cases misunderstanding me.)

I *like* explicit self for instance variable access. There are
arguments for and against, and my personal opinion is that the
arguments for are stronger. Local variables and instance variables
should be explicitly differentiated somehow, for the sake of
readability. Python's approach works. I slightly prefer Ruby's @,
because I think the brevity is a net win for something so commonplace
(is it less readable? Maybe. is "def" less readable than "define"? I
don't know - I think about 10 seconds of coding in Python or Ruby is
enough for you to be able to instantly grok def. Likewise, @. The
argument is more aesthetic IMO - how many perl-style/1337speak pu|\|
(tu@t10n m@r|<$ can you stand?)

I have come to dislike explicit self in method argument lists. Sure,
there are reasons. I don't think they're at all strong enough.

I'm definitely against the != behaviour, and maybe will get around to
actually PEPing it.

The point I was trying to make originally was that applying any mantra
dogmatically, including Explicit is better than implicit, can lead to
bad results. Perhaps having Practicality beats purity is enough of a
reminder of that fact for the Python community :)
 
T

Terry Reedy

Paul said:
He wrote the following of relevance:

"I added some classes to code that had previously just been functions,
and you know what I did - or rather, forgot to do? Put in the 'self'.
In front of some of the variable accesses, but more noticably, at the
start of *every single method argument list.*"

And rounding off with this on the subject:

"The problem is that the explicit requirement to have self at the
start
of every method is something that should be shipped off to the
implicit category."

There is no requirement to have 'self' in the parameter list. It can be
's', 'this', 'me', 'yo'(Spanish for I), or 'cls' (for class methods), or
any other identifier in whatever language.
In 3.0, identifiers are not restricted to ascii but can be any unicode
'word' as defined in the manual.

So the proposal would have to be that the compiler scan the function
body and decide which dotted name prefix is the one to be implicitly
added. Have fun writing the discovery algorithm. However, I think this
is pretty silly. Just write the name you want.

Or the proposal would have to be that 'self' is mandatory for all
programmers in all languages. I think *that* would be pernicious.
People are now free to write the more compact 's.sum = s.a + s.b + s.c'
if they want instead of the 'self' version. And again, not everyone
writes in English.

tjr
 
M

Matthew Fitzgibbons

Jordan said:
Well this discussion is chugging along merrily now under its own
steam, but as the OP I should probably clarify a few things about my
own views since people continue to respond to them (and are in some
cases misunderstanding me.)

I *like* explicit self for instance variable access. There are
arguments for and against, and my personal opinion is that the
arguments for are stronger. Local variables and instance variables
should be explicitly differentiated somehow, for the sake of
readability. Python's approach works. I slightly prefer Ruby's @,
because I think the brevity is a net win for something so commonplace
(is it less readable? Maybe. is "def" less readable than "define"? I
don't know - I think about 10 seconds of coding in Python or Ruby is
enough for you to be able to instantly grok def. Likewise, @. The
argument is more aesthetic IMO - how many perl-style/1337speak pu|\|
(tu@t10n m@r|<$ can you stand?)

I have come to dislike explicit self in method argument lists. Sure,
there are reasons. I don't think they're at all strong enough.

I'm definitely against the != behaviour, and maybe will get around to
actually PEPing it.

The point I was trying to make originally was that applying any mantra
dogmatically, including Explicit is better than implicit, can lead to
bad results. Perhaps having Practicality beats purity is enough of a
reminder of that fact for the Python community :)


Having followed this entire discussion, I don't think that explicit vs.
implicit is really the issue. Your own examples, self in the arg list
and __ne__ not being the negation of __eq__ by default, seem to
contradict your premise that explicit is dogmatically favored over implicit.

Keep in mind that another core principle of Python is "don't make the
user type it if they don't have to." As you yourself admit, there are
very compelling reasons to make the user type self in every method
argument list, one of which being yet another Python principle,
readability. Therefore, explicit self didn't come through dogmatic
adherence to explicit over implicit, but through careful consideration.

As for !=, it seems like there is a technical reason for the behavior.
Remember, there is no default __ne__ method, so the behavior you want
would have to live in the interpreter. If __ne__ isn't defined, it would
have to try to call __eq__ and negate the result. Is there any other
lookup that is treated this way? It seems like a kludge to add this
special type of behavior for one case that doesn't seem to bother most
people anyway.

So really, this is about a couple annoyances you've found in a language
you otherwise like. And it seems like both can be addressed pretty
easily. PyLint, for example, already checks that self is the first
argument of methods. And since it has a plugin system, I'm sure you
could add a check for __ne__ if __eq__ is defined. You can turn off the
checks you don't care about and bind it to a key combo in your text
editor. Those annoying little errors will be exposed very quickly.

-Matt
 
B

Bruno Desthuilliers

Carl Banks a écrit :
Yeah, try telling that to the people who advise writing "if x" instead
of "if x==0", or "if s" instead of "if len(s)==0".

Anyone suggesting that 'if x' should be replaced by 'if x==0' should be
shot down before he even get a chance to write any code. But perhaps you
meant replacing 'if x' by 'if x != 0' and 'if s' by 'if len(s) != 0' ?-)
 
C

Carl Banks

Of course not.

I just think Explicit is better than Implicit is taken seriously by a
large segment the Python community as a guiding principle,

Yeah, try telling that to the people who advise writing "if x" instead
of "if x==0", or "if s" instead of "if len(s)==0".


Carl Banks
 
B

Bruno Desthuilliers

Matthew Fitzgibbons a écrit :
(snip)
As for !=, it seems like there is a technical reason for the behavior.
Remember, there is no default __ne__ method, so the behavior you want
would have to live in the interpreter. If __ne__ isn't defined, it would
have to try to call __eq__ and negate the result. Is there any other
lookup that is treated this way?

There are quite a few cases in Python where there are both a specific
magic method *and* a default behaviour based on another magic method if
the specific one is not implemented. Just out of my mind:
* __contains__ and __getitem__
* __iter__ and __getitem__
* __nonzero__ and __len__

Not to mention the fact that lookup rules even check the existence of
special methods on class attributes (remember the descriptor protocol ?)...
 
C

Carl Banks

Except when it comes to Classes. I added some classes to code that had
previously just been functions, and you know what I did - or rather,
forgot to do? Put in the 'self'. In front of some of the variable
accesses, but more noticably, at the start of *every single method
argument list.* This cannot be any longer blamed as a hangover from
Java - I've written a ton more code, more recently in Python than in
Java or any other OO language. What's more, every time I go back to
Python after a break of more than about a week or so, I start making
this 'mistake' again. The perennial justification for this 'feature'
of the language? That old Python favourite, "Explicit is better than
implicit."

I'm sure some people use that argument, but in my observations the
more common justification for explicit self is that makes code easier
to read, by making it obvious that something is a class attribute
instead of a local or global variable.

Your claim is that self makes code a lot harder to write, but you've
disregarded the viewpoint of the reader altogether. You probably are
aware that there is another Zen that says "Readability Counts". Would
you also suggest that Zen needs to be done away with?

If there was one change I could make to Python, it would be to get
that damn line out of the Zen.

Personally, I think you've applied it to things that it wasn't really
intended for. It's mostly applies to things like language syntax,
type conversions, and other semantics. For instance in Perl there are
cases where you can omit quotes around strings; that'd be a major no-
no in Python. Or how about this:

a = 1 # a is an integer
a += "hello" # oops, now it's a string

Let me suggest that such things are a Very Bad Idea and so that line
is better left in place.


Carl Banks
 
N

Nikolaus Rath

Terry Reedy said:
Because you must prefix self attributes with 'self.'. If you do not
use any attributes of the instance of the class you are making the
function an instance method of, then it is not really an instance
method and need not and I would say should not be masqueraded as
one. If the function is a static method, then it should be labeled
as one and no 'self' is not needed and auto insertion would be a
mistake. In brief, I assume the OP wants 'self' inserted in the body
because inserting it only in the parameter list and never using it
in the body is either silly or wrong.


I think you misunderstood him. What he wants is to write


class foo:
def bar(arg):
self.whatever = arg + 1


instead of

class foo:
def bar(self, arg)
self.whatever = arg + 1


so 'self' should *automatically* only be inserted in the function
declaration, and *manually* be typed for attributes.

Best,

-Nikolaus

--
»It is not worth an intelligent man's time to be in the majority.
By definition, there are already enough people to do that.«
-J.H. Hardy

PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C
 
B

Bruno Desthuilliers

Bruno Desthuilliers a écrit :
(snip)
There are quite a few cases in Python where there are both a specific
magic method *and* a default behaviour based on another magic method if
the specific one is not implemented. Just out of my mind:

s/out of my mind/Off the top of my head/

Pardon my french, and thanks to Tim Golden for the correction !-)
 
S

Steven D'Aprano

I think you misunderstood him. What he wants is to write


class foo:
def bar(arg):
self.whatever = arg + 1


instead of

class foo:
def bar(self, arg)
self.whatever = arg + 1


so 'self' should *automatically* only be inserted in the function
declaration, and *manually* be typed for attributes.


That idea might have worked many years ago, but not now. The problem is,
what happens here?

class Foo(object):
def foo(self, arg):
self.whatever = arg + 1
@classmethod
def cfoo(cls, arg):
cls.whatever = arg - 1
@staticmethod
def sfoo(arg):
print arg


How does the compiler know to insert "self" into the argument list for
foo, "cls" into that of cfoo, but do nothing for sfoo? Decorators can
transform methods in arbitrarily complex ways using the Descriptor
protocol.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top