Re: Advantages of function objects vs. classes/methods

Steven D. Majewski (sdm7g@elvis.med.virginia.edu)
Wed, 4 May 1994 16:45:36 -0400

On May 4, 19:22, "R. Anders Schneiderman" wrote:
>
> As I've been reading through sample python scripts, I've noticed that
> often people use a series of function objects rather than creating one
> or two classes that cluster the functions together. OO Purists would
> have a heart attack if they saw this, arguing that function objects
> are precisely what we want to avoid: they don't fit well with OOA/OOD
> (since function objects take your attention away from the data) and
> are less likely to promote long-term reusability [ ... ]
>
> I'm no purist (IMHO, python is much more readable than Smalltalk or C++),
> but personally I'm more comfortable using classes than function objects.

Python is certainly not a language for purists. ( OO or other )

(1) You are not *forced* to program in an OO style, and in fact you can
do quite a lot without ever using Classes. But often, using Classes
is the easiest way to implement something and it's usually the most
understandable/maintainable/reusable.

(2) Modules are another way to "cluster functions together", and if
there is no need for the functions to maintain multiple independent
states, they may be more appropriate than Classes. If there is
only ever supposed to be one single instance of something, and
initialization is only supposed to be done once, module oriented
code would seem to make more sense that trying to force this
behaviour out of a class. ( But it can be done: make all variables
class variables, and keep an instance counter and don't create
more than one instance. However, if you want the 2nd invocation
of Class() to just give you an alias ( sort of mimicing the fact
the multiple import statements execute the module code ONCE - but
they all provide a way to get at the namespace ) to that single
object, then you're asking for something pretty tricky just to
keep it "object-oriented" ! )

(3) Since not all python objects are classes, ( and not everything in
Python is even an object in the way that they are in SmallTalk ) a
mixed style of programming is sometimes required.

(4) Some functions like len(), map(), etc. are NOT methods, but are
generic functions that work on any sequence like object. In the
case of len(), an Class must provide a __len__() method for the
generic function to call. But map() applies a function to the
elements of one or more sequences, and as long as each sequence
IS enough of a sequence to provide __len__() and __getitem__()
it will work for all of them. Providing a map method for each
sequence would only be confusing.

We could drag this into a theoretical discussion of ADT vs.
Classes+Inheritance, functional vs. O-O, multi-methods and
signatures, etc., [ look in comp.object any day for that
argument ] but the real reason is that Python is not
a purist/theoretical language and it doesn't dictate a particular
programming style ( except in a few places where Guido's
personal preferences show thru, and in most of those, I don't
think it was ideology that lead him to certain design choices,
so much as "doesn't everybody do it like this? - I can't imagine
why someone would want it any different" assumptions. )

> What I was wondering was:
> 1) Are there any overwhelming conceptual advantages to using function
> objects over classes?
> 2) If I choose to use classes instead of function objects, will I pay
> a heavy penalty in speed?

I wouldn't say a "heavy" penalty, but in general, every 'dot' in a
name means another attribute lookup. So "var" is faster than
"module.object.var". That goes for method lookup too, so if you
are concerned with cycles in a particular loop, you might want to
front load it by changing (for example):

for thing in sequenceA:
sequenceB.append( thing )

to:

Bappend = sequenceB.append
for thing in sequenceA:
Bappend( thing )

Instance attribute lookup is chained from the instance to the
class to the base classes, so instance.method() can be more
than one lookup.

And there is certainly a penalty is moving from a builtin object
like lists or dictionaries to a Class defined object that does
the same sort of thing.

But if you're using Python, I think that implies that you have
already made a decision that development time is more dear to
you than run time - at least for the present - so I wouldn't
suggest you adopt a Class-less programming style for the
sake of effeciency.

- Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU>
- UVA Department of Molecular Physiology and Biological Physics
[ Desparately seeking "Candy Bullets and Moon" ! ]