[E-Lang] newbie syntax exploration: Python O-O syntax

zooko@mad-scientist.com zooko@mad-scientist.com
Tue, 27 Feb 2001 18:43:02 -0800

> I have sort of lost track of what the alternatives for object-constructor
> patterns are at this point.

And I have never yet learned the alternatives available in E.  :-)

> Zooko, how would you make something that has the
> Python qualities you described that sound so attractive? What would
> constructors and functions look like?

Um...  <gulp>  Well I haven't really learned E yet, so anything I say
might be embarassingly stupid.  But I'll forge ahead in the hopes that
it will be useful to learn what sorts of embarassingly stupid things
newcomers are likely to think...

I learned BASIC, an assembly language, Pascal, Modula-2, C, C++, Perl,
Java, Python, in that order.  (I also learned a little bit of Haskell,
but we can safely ignore that I think...)

When moving from Java to Python, I found it to be delightfully easy --
certainly the most painless ramp-up I had ever undertaken.  Within one
day I was writing Python in order to implement my ideas rather than in
order to learn Python.

In Python, you define a class with specific syntax:

>>> class SpamLump:
>>>     def __init__(self, radius, consistency):
>>>         self.area = radius * radius * PI
>>>         self.consistency = consistency
>>>     def taste(self, numtimes):
>>>         for i in range(numtimes):
>>>             print "%s inches of %s gooey goodness." % (self.area, self.consistency)

(Now the underlying object model is actually a dynamic object-based
model rather than a Java-style class-based model, but 90% of Python
programmers don't know that, although they may occasionally wonder at
how the object model manages to keep *not* get in their way...)

To create and use an instance of this class, I write:

>>> s = SpamLump(3, "tough")
>>> s.taste(3)
12.56 inches of tough gooey goodness.
12.56 inches of tough gooey goodness.
12.56 inches of tough gooey goodness.

So the only things I had to learn, coming from Java, were that the
"constructor" was named "__init__()" and that each method had to have
"self" as the first argument.

Now under the hood (and directly accessible to any Python programmer)
the "class" keyword simply defined a function named "SpamLump" for you.
The function `SpamLump()' allocates space for an object, assigns
"taste" to be a member of that object, invokes the `__init__()'
function passing the new object and any args, and returns a reference
to the new object.

So Python programmers routinely instantiate new objects with
`Mumble()', and routinely invoke functions with `blather()', which can
occur in the same scope and are completely indistinguishable except for
a non-enforced convention that class constructor functions always have
first-letter capitalized and functions (and methods) never do.

Pythonistas still retain all of the flexibility of treating
constructors just like functions, which are first-class, so we can
store them, create them dynamically, invoke them with `apply(myfunc,
someargs)', etc.  We also enjoy being able to dynamically replace
someone's constructor with a function of our own design which does
something different under the hood but behaves the same way by
returning a new object.

Nobody, AFAIK, has ever been confused about thinking that a line of
code was creating a new object when it wasn't or vice versa.

And we don't use "Maker" anything.  It's just `Thingie()' to create a
thingie.  Anytime you see `varname = Whatsit(args, blargs, flargs)',
you know that a new Whatsit has just been created.

I hope this helped, either by giving you a good example of how to do it
or else a good example of how not to do it.  ;-)