Well, for kicks I looked at the standard Python library, since I figured it
would have the greatest concentration of unbound method use (my reasoning was
that since it was a library more than a consumer of a library, you'd have lots
of class hierarchies and therefore more occurences of unbound method calls to
super classes. Even in this situation it appears that unbound method calls are
less than 2% of all method calls. The real point is simply that unbound method
calls are pretty rare.
I appreciate your taking the time to actually research this question.
The 2% number for unbound functions doesn't surprise me. It would be
interesting if we could get similar statistics on static methods, but
I suspect the numbers would not be meaningful, given that the
staticmethod syntax is relatively new, and there is a long tradition
in Python of using various alternatives to static methods. New users
tend to copy traditions, which is OK, except that learning those
traditions is time-consuming.
To me, the real question is how often will my kind of users (no prior
experience with Python traditions or OOP, just writing what "comes
natural") - how often will they need a static method? That depends on
the size and complexity of the programs they are working with. My CDP
program will be fairly large, and I am using static methods without
hesitation. I would guess half the programs they will encounter would
have a static method here and there.
Not at all - that's a flawed analogy because variable names can be pretty
arbitrary and interchangable. The different types of function calls, method
invocations, whatever, are neither arbitrary nor interchangable.
Here is a better analogy than my "no-q" functions. I will use the
term "global method" to mean any method containing a global variable.
We now have "normal methods", "static methods", "global methods", and
a few others. There is no difference in the calling sequence or the
header line between a global method and a normal method. Yet we don't
seem to have any need for a statement like
myMethod = globalmethod(myMethod)
I'm beginning to understand the real root of the disagreement - you see no
value in the differences and therefore see the existence of the differences as
a flaw. But that's just the problem: these are not merely syntactic
differences, but they are semantic - they are different in purpose and in use,
so your suggestion to get rid of them seems very unappealing: from my
perspective you are removing something useful from the language to solve a
"problem" that I've yet to encounter, or seen anyone else encounter (including
new users of the language).
And this is why the proposal seems so lousy: the difference between a static
and a non-static method is _not_ just a syntactic difference, their existance
is not _caused by_ the syntax. The syntax merely reflects that they are
different things to begin with. They are different tools, different features -
you use them for different things, so making them appear identical to the
maintainer of the code and the caller of the code seems like a really bad
idea - a maintenance nightmare. If you remove any syntactic difference, then
that information is lost from the code itself. But since that info is useful,
people will instead track that info in comments or something - yuck.
No, no, no - they are different tools, plain and simple. The difference just
isn't skin deep - changing the syntax won't make them go away, it'll instead
make the language more ambiguous. Without meaning to be offensive, I must ask:
how much have you actually used any of these features you're interesting in
consolidating? (static method, unbound methods, bound methods, etc.)
I'm new to Python and object-oriented programming. I make no claim of
language expertise or vast programming experience. I'm simply
offering a perspective on Python from a technical professional
(circuit design engineer) who intends to use it as the basis for a new
design platform, and intends to recommend it to students and other
technical professionsls who could benefit greatly, but don't have time
to learn the language as well as they should.
That's just my point: after consolidating the syntax, static methods will still
exist, but there will be no way of knowing which ones are static and which ones
aren't _without reading every line of the code_ - there will be no syntactic
way to express the idea. Egads!
Yes, I understand that it looks that way to you, but why is it that so many
people who have used the language for a long time disagree with you? Is it
because everyone else has blinders on? Could it be _possible_ that these
features have value and/or that the solution you propose is worse than what
currently exists?
Saying everyone has blinders is too harsh. It's more like the
particular group of users in this discussion are more advanced than
the users I am concerned about, and the lack of unity in
function/method syntax is a minor issue they have "sailed past"
without even thinking.
I have a similar reaction to problems that bother less technical
users, like the need for a special operator to indicate "floor
division" or the problems with storing decimal fractions in a binary
floating-point number. These all seem pretty obvious to me, yet I
appreciate that Python makes an effort to accomodate these "naive"
users.
Again, how much did you use the language before coming to the
conclusion that you have?
see above
I guess my real gripe with the proposal is that it takes what is currently
clear and makes sense and combines it in such a way to make it ambiguous to
everyone involved with the code. The features you propose consolidating really
are different in real programs, and making them all look the same just for the
heck of it doesn't seem to make much sense.
proposed syntax?
Understand my code 6 months from now. Modify the code with less risk.
Understand the level of intent in someone else's code I'm using.
OK, here is what I can extract from all this: Having a separate
syntax for static methods is beneficial because it tells the
programmer at a glance that he can call a method from a class without
having an instance of that class at hand.
I can see this as a fundamental advantage of the current syntax, but I
would still question the value of this advantage, assuming that static
methods are rare. I would still opt for the unified syntax, and
accept the burden on rare occasions of having to scan the body of a
method (not "read every line") looking for the presence of instance
variables. Perhaps this is why Ruby highlights them with @. I think a
bare leading dot is pretty obvious, but now we're getting down to
personal preference.
If the need to quickly determine if a method is "static" is really an
issue, I would say, don't muck with the standard calling sequence, but
put a special "decorator" on the header line. I think that is being
proposed in PEP 318. Having this decorator could provide the same
fundamental benefit as the statement myMethod =
staticmethod(myMethod), and this does not require a special first
argument.
No, that burden is on your shoulders, as everyone not in favor of your
suggestions can let the thread die off and nothing will change. <0.5 wink> In
You left out a piece of the prior discussion. You said that I was
either ignorant or choosing to ignore the benefits of the current
syntax. My response was "show me" such a benefit. Now you seem to be
saying the burden is on me to show I have thought of everything.
Obviously, I can't do that. Equally obvious is that you could show me
one example of what you are talking about and prove your point.
I think if we both forget about trying to win an argument, and dig for
the facts wherever they may lead, we can avoid these deadlocks.
another thread I suggested you take the time to learn what the 2 or 3 most
common uses are for each of the features that will be affected, and show both
the implementation and use in current Python and after your proposed changes.
Not only will doing this give a clear example to everyone, it'll also show that
you are at least aware of how the different function/method forms are used
today in _real programs_ and not contrived examples - after re-reading some of
your comments I have my doubts.
I have shown the 4 function/method forms I'm aware of, and how to
translate them to a simpler syntax, in Appendix 1 of Prototypes.doc at
http://ece.arizona.edu/~edatools/Python Have you read that?
Again, we can avoid deadlock by focusing on the facts in front of us
and avoiding the argument "I'm a better expert than you, so I win."
We'll either get to the bottom of an issue, or agree that its a matter
of personal preference.
All of those guiding principles are subjective, but IMO it's pretty clear here
Equally clear from my perspective.
I abhor Java, actually, and I'm not even sure how to do the bound method form
in Java (or C++, which is where my background lies more than Java).
Please understand that these are not arbitrary. The fact that you think they
are arbitrary makes me wonder if you really understand them. Don't be offended!
Again, you deleted the context. This is in response to your statement
that there are only a handful of rules a beginner needs to adhere to.
I do understand most of these rules (all but the strange example
earlier in this thread). However, I would like to eliminate *some* of
them, and keep just one: If you call a function from an insstance, you
get a bound function. Otherwise all references to the function are
unbound. Even the strange example will do exactly what you expect.
Prothon, by the way, eliminates even this rule, following a little too
rigidly the dictum "explicit is better". Their so-called explicit
binding syntax is a mess. I much prefer Python's implicit syntax.
"Practicality beats purity."
What I like about the current syntax, is that you don't really need to memorize
any rules because how you call them is pretty obvious, unless of course you're
not thinking about what you're doing, in which case there are bigger problems
at hand. For example, when I learned Python I never came across some tutorial
showing how to do an unbound method call - I got to the point where I needed
it, I tried the most obvious thing, and it worked. Likewise, the first time I
needed to get a reference to a bound method, I was impressed that the first
thing I tried worked (impressed with the language, not with myself
).
It didn't go quite as smoothly for me, probably because I was rushed
on my other projects, and also because I had no prior experience with
OOP. I learned about bound and unbound methods by reading Learning
Python, but it didn't really sink in until I started using them. I
don't expect my students to learn these topics in the short time we
have in class. Most of them will not be writing complete programs, so
I don't expect them to pick it up later, either. Most of them will be
modifying scripts that have been written by someone with more
expertise in Python. A working knowledge of Python up to, but not
including, the OOP chapters is sufficient for most.
My interest in OOP is not only for what it can do in my own programs,
but I see Python OOP as beautiful and elegant (but not perfect), and
something that EE's could really benefit from over their entire
careers. I will be using it heavily in my own programming, but not
expecting my students to learn it. It's right at the edge of what
they need to know to run the circuit design tools. That's why I'm so
interested in simplified OOP, and uninterested in floor division or
metaclasses.
Like I said, if you really are interested in making headway with your proposal,
*you* need to demonstrate through some non-contrived examples that you
understand how things work today. I've read the pages on your site and either
they don't show all cases that will be affected, or the examples are too buried
by other changes so I missed them. So, show a few examples of how bound methods
are implemented and used today in Python, and how they'd be used and
implemented the new way. Show a few examples of how unbound methods are
implemented and used today, etc. Just showing one example and stating that
everything will be like that glosses over the fact that these things are all
used in very different ways today, and leaves the reader wondering if you have
really thought things through.
I think I've done my part on this. The best examples are in
Prototypes.doc at
http://ece.arizona.edu/~edatools/Python/
I'm also continually adding new examples under the Examples and
Exercises link on that same page. Many of these are contributed by
readers of this thread, including some who would rather not post here.
(Gentle Request: A little less intolerance from some others on this
thread might encourage more contributions from people they really need
to hear from.)
As for a real program, it will be a few months before I have anything
sizable. I showed you the statefile example (in response to your
request), but you seemed to be insulted, like you thought I was
talking down to you, or something.
I think the gap in our perceptions can be bridged by focusing on
examples. I have to do a lot of work to extract from general
criticism and dogmatic statements, anything that I can translate into
a specific example. Anything you can do to clarify your statements
with examples will be greatly appreciated. The 'bag' example was
perfect.
Look at the changes to Python, especially over the past few years - many of the
features are publicly credited as having come from other languages.
Yes, and that is one of the things I like about Python. GvR is not
hesitant to make changes when those changes improve the language. I'm
also impressed with the attention to beginners concerns, like the
integer division problem. GvR has a remarkable combination of
language genius and understanding of beginners' problems.
-- Dave