python without OO
dave.benjamin at gmail.com
Thu Jan 27 11:30:41 EST 2005
> Is it possible to write purely procedural code in Python, or the OO
> constructs in both language and supporting libraries have got so
> embedded that it's impossible to avoid them? Also, is anyone aware of
> any scripting language that could be considered as "Python minus OO
> stuff"? (As you can see I'm completely new to Python and initially
> believed it's a nice&simple scripting language before seeing all this
> OO stuff that was added in over time)
Many people have answered your question already, but I thought I would
share my opinion as well, since I think I understand where you are
What attracted me to Python was not OO at all but the fact that it was
somewhat similar to PHP (which I was using heavily at the time) but
allowed me to encode certain higher-order programming techniques that
PHP simply could not express. In short, I had become interested in
functional programming after reading David Mertz's "Charming Python"
tutorials, and after x attempts at trying to port the ideas to PHP, I
finally gave up in frustration and started learning Python.
At the time, I was decidedly anti-OO. I grew up around a very liberal,
punk-rock, nonconformist culture, and the amount of hype around OO made
it too easy to hate (and, I suppose, it still does). PHP at the time was
90% procedural; the prevaling attitude (which seems to have changed with
the advent of PHP5) was that procedural code is all you need to solve
most problems. With web scripting, it kind of makes sense, because
(IMHO) objects really don't have much value unless you can hold onto
them long enough for them to be useful, and many web scripts just pipe
data from one place to another. Packing the data into objects is kind of
like putting your possessions into boxes so that you can move them from
one room to another and immediately unpack.
So, I guess you could say, I learned Python in spite of its rich support
for OO. =)
It wasn't until I had to implement a large (to me), complex, graphical
user interface, that I finally had to get off of my soapbox and realize
that I had no better way to create sophisticated GUIs than OO. There are
surely non-OO ways to build fancy GUIs, like functional-reactive
programming, but a) I don't understand them, and b) I had to get my
project done, and used the tools I had and the techniques I knew.
At that time, I started learning about Smalltalk and Alan Kay's emphasis
on the "messaging" aspect of OO, and it started making a lot more sense.
One of the most difficult tasks sometimes is getting various parts of
the screen to update when the user changes a field or clicks a
button--in a way that is manageable and doesn't devolve into spaghetti.
Aside from GUIs, however, I am rarely confronted with a task where I
*need* OO. As a method for encoding abstract data types, it works, but
it seems like more fashion than substance. As many have pointed out, the
difference between "method(obj, args)" and "obj.method(args)" is subtle,
and often inconsequential. In Python, you can program with just modules
and functions/procedures, and never bother with the fact that you are
using objects. Sure, a module is an object, and so is a procedure, but
it's not all up in your face like, say, Java's arcane restriction that
everything belong to some class.
It has been said of Perl programmers that they often dislike
abstraction. Sometimes, I really sympathize with this viewpoint. I hate
having to use a class that offers no value to the problem whatsoever,
merely because an API is hard-wired to use instances of that class. No
abstraction can often be better than a bad abstraction, and when it
comes to debugging, the last thing you want is a bunch of black boxes.
These days, I do use classes and objects in Python, but mainly as a code
organization technique, and only when I actually want my code organized
that way. I tend to start with the problem at hand, building procedures
to remove redundancy and keep my code small and simple. If I start
noticing that a lot of procedures revolve around a particular data
structure, I refactor them into a class. This way, I avoid creating
abstractions that don't fit. It's much more mechanical than any feigned
attempt at "modeling the real world".
I think that functional programming (FP) is a very powerful methodology
that can solve a lot of the same problems as OO, and does some things a
lot better. FP and OO can live in harmony to some extent, but there are
some places where they contradict each other. For instance, FP offers a
mind-blowingly powerful tool called pattern matching, which is like a
switch/case statement on steroids. OO dogma insists that this "violates
encapsulation", and that any form of switch/case is evil... replace
conditional with polymorphism... replace conditional with
polymorphism... replace conditional with polymorphism... repl<hic> On
the other hand, implementing something as seemingly simple as a
"__str__" method in functional languages can be surprisingly non-trivial.
The lesson to be learned here is that each methodology (including
strctures/procedural) has its strong points and weak points, and there
are always tradeoffs to be made. OO's biggest strong point is that a lot
of people grok it, so it's a fashionable and friendly user interface for
a programmer. Python in particular emphasizes this point with its
no-nonsense, lightweight approach to defining classes and using objects.
However, and this really the main point I wanted to make: *no* paradigm
is sufficient to solve any interesting problem. I have gotten sucked
into coutless language and paradigm pissing matches only to go back to
my desk and try to finish a project I'm working on and realize that
(gasp!) programming is still hard. It never stopped being hard! And
sometimes the methodologies just create additional work (cf. jwz's
comment on regular expressions: "now you have two problems").
The best way to crack through tough problems is to learn as many methods
and techniques as you can, and develop an intuition for "the right tool
for the job". What matters most is that you solve the problem at hand,
in a way that people can hopefully understand and maintain later.
More information about the Python-list