Unification of Methods and Functions

James Moughan moughanj at tcd.ie
Fri May 7 09:31:51 EDT 2004


David MacQuigg <dmq at gain.com> wrote in message news:<knfl90tes9m608n99jn9lfcnpij5gqemaf at 4ax.com>...
> On 6 May 2004 08:37:50 -0700, moughanj at tcd.ie (James Moughan) wrote:
> 
> I don't want to argue implementation details, as I am no expert, but I
> think you are saying something is wrong at the user level, and that
> puzzles me.
> 
> A global function, if I understand your terminology correctly, is one
> defined at the module level, outside of any class.  Such a function
> cannot have instance variables.  If you were to reference that
> function from within a class, it would just act as a normal function
> (a static method in Python terminology).  I can't see the problem.
> 

Let me give an example:

def getLength(s): return s.length

class Foo:
    length = 5

Foo.getLength = getLength

foo = Foo()
print length(foo), foo.length()

A method in a class in Python is just like a global function; for a
global function to operate on an object, it must take it as an
argument. The prototype syntax would appear to break the above
example.

> The difference in the proposed syntax is that it doesn't need the
> staticmethod wrapper to tell the interpreter -- don't expect a special
> first argument.  In the new syntax all functions/methods will have the
> same calling sequence.

If a method doesn't operate on the data from an object then as a rule
it should be global.  There are exceptions, but they generally don't
occur in Python so much as a in 'true oo' language like Java.
 
> I've looked at a few introductions to Python, and in my opinion
> Learning Python, 2nd ed, by Mark Lutz and David Ascher is the best.
> It strikes a good balance between the minimal presentation that
> tersely covers the essentials for an experienced programmer vs the
> long, windy introductions that put you to sleep with analogies to car
> parts and other "objects".  Lutz takes 95 pages to cover OOP.  I think
> I could do a little better, maybe 70 pages, but that may be just my
> ego :>)
> 
> When you say ten pages, you must be making some very different
> assumptions about the students or their prior background, or the
> desired level of proficiency.  The least I can imagine is about 30
> pages, if we include exercises and examples.  And that 30 assumes we
> get rid of all the unneccesary complexity (static methods, lambdas,
> etc.) that currently fills the pages of Learning Python.
> 

I'm assuming they alreay know the general structures of programming in
Python, and that you can then just show them how to package data and
methods into a class with a clear example, by rewriting a program
you've shown them before.  After that it's mainly a question of
explaining why you should do it, which is probably rather more
important than how.

I've never met anyone who had difficulty in understanding anything
about the syntax of OO other than the class/object distinction.  It's
fundamentally very simple once you have a basis in all the other
programming techniques.

Unless you're talking about the entire programming course, 70 pages is
waaay too much - your students just will not read them, regardless of
how brilliant they are.

> >There are static methods in Python? :)  In my coding the major reason
> >for static methods is for data encapsulation for singleton-style
> >elements.  Python has no data encapsulation worth anything, so static
> >methods don't do much that's useful.
> 
> We have the usual dose of terminology problems here.  The term 'static
> method' in Python may be different than in other languages.  In Python
> it just means a method that has no instance variables, no special
> first argument, and an extra 'staticmethod' line, to tell the
> interpreter not to expect a special first argument.
> 

OK; no particular difference from Java/C++/etc.

> Python does have "encapsulation" but does not have "hiding", by my
> understanding of these words.  The idea is that __private variables
> are easily identified to avoid accidents, but there is no attempt to
> stop deliberate access to such variables.  This is a design philosophy
> that I like.
> 

*Nods*  That's why I said 'worth anything'; the idea of encapsulation,
in theory, is to prevent screw-ups, which is why hiding is key. Not
that it's necessarily a good theory. :)  I also like Python's
philosophy here.

> >
> >I must note that Animals_2 is a total abuse of OOP techniques.  You
> >continuously define classes to do the same thing, repeat the same code
> >in each, then give them slightly different names.
> 
> This is a textbook introduction, not a real program.  The purpose of
> the example is to show a complete OOP hierarchy in a small example,
> with a good selection of the method styles most needed in a real
> program.  The similarity between the show() methods in different
> classes would not be so tempting to reduce to one global function if I
> had made a larger example, with more radically different outputs from
> each show function.  I thought that just changing one string in each
> function would be enough to say "This function is different."
>

OOP is a tool.  It's abstraction makes it tempting to create arbitrary
structures as examples, but doing that looses any sense of the reason
why you would use that tool.  That's why I see people with CS degrees
who can throw around objects and heirarchies at will but who can't
structure a simple program effectively.
 
> You are not the only one who had this reaction.  See my reply to Don
> Cave above.  I guess I need to thow in a little more "meat", so that
> experienced programmers don't get distracted by the possibility of
> making the whole program simpler by taking advantage of its
> regularities.  This is the same problem I've seen in many texts on
> OOP.  You really can't see the advantages of OOP in a short example if
> you look at it with the attitude -- I can do that much more easily
> without classes.  It's when you get to really big complex hierarchies
> that the advantages of OOP become clear.
> 

Learning to program is about 5% how to do something, and 95% when and
why you should do it.  You seem to be focusing almost exclusively on
how, which I suspect is why we're all so upset :) you get that way
when you have to fix the code which eventually results.


> >Also, your show method is IMO more than dubious.  show does not
> >logically belong to Feline.  As a result you are using a class to
> >display data about other classes to which it is not connected.  This
> >is not OOP.
> 
> I thought this part was pretty clear.  The show() method at each level
> calls the show() method one level up, then adds its own stuff at the
> end.  Feline.show() calls Mammal.show(), which prints lots of stuff
> characteristic of mammals, all in a format unique to the Mammal class.
> Mammal.show() in turn calls Animal.show().  At each level we have some
> unique display of characteristics.  The purpose is to have a call at a
> particular level show all characteristics of the animal from that
> level up.
> 

It is clear, just not a good idea.

> >If I were teaching someone and they produced this structure then I'd
> >go over the rationale with them and try to figure out where they went
> >wrong in their planning of the program, and maybe go back and tutor
> >them on the basic ideas of OOP.  I would not change the language to
> >make it easier to do in future.  :)
> 
> Both responses I have on this are basically experts saying -- you can
> solve this particular problem more easily by restructuring it.  I
> should have been more clear.  Imagine that each of these classes and
> methods is fully expanded with lots of parameters to make each one
> unique.  Don't even think about re-structuring, unless you are trying
> to tell me that the whole idea of having these structures in any
> program is wrong.  That would surprise me, since this "animals"
> example is a common illustration of OOP.
>

OK: "The whole idea of having these structures in any program is
wrong."

Firstly, the program uses a class hierarchy as a data structure.  That
isn't what class heirarchies are designed for, and not how they should
be used IMO. But it's what any bright student will pick up from the
example.

Secondly, it breaks the entire concept of OOP.  Objects are designed
to be individual entities with side-effects restricted to their scope,
in order to modularize programs.

In this example, you use side effects from one class to influence the
output of another; a bovine will end up influencing the output of a
cat, for example.  And the effect in completely implicit.  As a
result, someone who is introducing a mouse class can break another
part of your system without the faintest idea that they are affecting
it.  It's a fragile structure leading to the almost inevitable
creation of the most intractable type of bug.

The fact that Python makes it hard to do is *good*.

 
> What I'm looking for is not clever re-structuring, but just a
> straightforward translation, and some comments along the way -- oh
> yes, that is a little awkward having to use a staticmethod here.  Wow,
> you mean staticmethods aren't fundamentally necessary, just a bandaid
> to make up for Python's deficiencies?  That was my reaction when I
> first saw Prothon.
> 

Static methods are more like a band-aid to make up for the
deficiencies of OOP.  Python isn't a pure OO language, and doesn't
suffer the need for them badly.

> Thanks again for your feedback.
> 
> -- Dave



More information about the Python-list mailing list