Unification of Methods and Functions

David MacQuigg dmq at gain.com
Mon May 24 17:17:36 EDT 2004


On Sun, 23 May 2004 21:23:43 -0600, "Dave Brueck"
<dave at pythonapocrypha.com> wrote:

>David MacQuigg wrote:
>> >> I can't comment on the usage statistics you cite, but it seems to me
>> >> that unbound methods are more important than these statistics would
>> >> imply.
>> >
>> >All I'm saying is that for most programs, the bound method form is way, way,
>> >way more commonly used than is the unbound calling form.
>>
>> I would agree if you cut out two of the "ways" in this sentence. :>)
>
>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.

>> Still this is like saying names that start with the letter 'q' are way
>> less common than all other names, so it is OK if we have a special
>> form for functions with such names.
>
>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've never stated or implied that unbound methods are as common as
>> bound methods.  Nor would I say that confusion abounds.  The different
>> calling sequences are just an unnecessary complexity that trips up
>> some new users, especially those that don't have experience in some
>> other OOP language.
>
>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).
>
>> ><sigh> I know what static methods are _for_, but I don't see what is
>> >necessarily complex about them, nor how your proposed unification would
>help -
>> >in fact, ISTM that it would make it much more confusing because both the
>> >implementor and caller of the code would never be quite sure if the method
>was
>> >a static one or not, and that's something that needs to be known by both
>> >parties.
>>
>> I think you have not understood the proposal.  It is *not* necessary
>> in the new syntax to know the difference between a static and
>> non-static method.  There *is* no difference.  A "static method" (a
>> function without instance variables) simply ignores __self__.
>
>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.
>
>> The differences are an artifact of the syntax, not any fundamental
>> difference in purpose.  Normal methods have a special first argument.
>> Static methods do not.  That's all there is to it.
>
>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.

>> If there is were some fundamental purpose to static methods, there
>> would be something they can do that can't be done with the proposed
>> simpler syntax?
>
>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!
>
>> I may be wrong, but it looks to me like there *are* no benefits of the
>> current binding syntax over the proposed syntax.
>
>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

>> What are the benefits of the current design?
>
>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.
>
>> What can you do in the current syntax that can't be done more easily in the
>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.

>> Show me some code, and I will show you the equivalent in "Python 3".
>
>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.

>> >> When you say the distinction between methods and functions makes
>> >> sense, I assume you mean it has some value to the user.  I would like
>> >> to hear more about this, because I am assuming just the opposite.
>> >
>> >Yes it has some value, but more than that: it fits the brain quite well. IMO
>it
>> >adheres to the principle of least surprise,
>>
>> The Principle of Least Surprise has always been one of my favorites.
>> It's a shame this principle offers us so little guidance in resolving
>> a simple issue like this unification question.
>
>All of those guiding principles are subjective, but IMO it's pretty clear here
>:)
Equally clear from my perspective.

>> us in opposite directions.  I think the difference may be in our
>> backgrounds.  You seem quite comfortable with Java, so I would guess
>> these different method forms fit with what you have learned there.
>
>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).
>
>> I need to feel like I understand what is going on.  I'm not
>> comfortable with a bunch of arbitrary rules
>
>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.

>> I need specific examples of problems introduced by the new syntax, or
>> of something the old syntax can do better.  We can argue general
>> principles forever, but one good example will settle this question.
>
>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.

>> We can learn a lot by looking at
>> how languages designed *after* Python have tried to improve on it.
>
>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




More information about the Python-list mailing list