John Nagle said:
This must be from someone who hasn't used threads in Python.
Wrong again.
The usual way to write a thread in Python is to subclass
"threading.thread". The subclass provides a "run" function, which
will be called from the new thread.
Yes, it is. Does that conflict with what I wrote? No.
If you want you class to have a private thread, make /another/ class to
represent the behaviour of this private thread, and attach an instance
of this to the first class. Or you can pass a closure or a bound method
to the thread constructor. (That's probably cleaner, actually, but
doesn't fit culturally.)
Not exactly. I collect programming languages like some people collect
postage stamps; it gives one a useful perspective. I mentioned those
languages because they seem most historically relevant. Zetalisp's
`Flavors' system introduced multiple inheritance; Common Lisp and Dylan
fix the linearization properly (eventually culminating in the C3
linearization algorithm); Scheme has no standardized object system, but
there are a number of -- mainly CLOS-like -- object systems available;
and Smalltalk is both the classic dynamic object-oriented language and a
single-dispatch contrast to the CLOS/Dylan generic-functions approach.
Of those, I've written code in Common Lisp, Scheme, and Smalltalk.
Most of the LISP variants really did objects very well; objects were
an afterthought. Smalltalk went a bit too far in the other direction;
the "everything is an object" mindset was overdoing it.
CLOS actually does a remarkable integration job, bringing the existing
types into the object system; but, yes, the seams are still visible,
because you can't subclass some of the classes.
Python is reasonably well balanced in the object area. Everything
isn't an object. There are explicit classes, unlike the
instance-copying model of Self and Javascript.
Is that a major win? Self's prototype-based approach seems quite
capable of expressing anything you might want to express with classes,
and a few other things besides. (The implementation works by attempting
to deduce class structures dynamically, so there's an isomorphism here,
of a sort, but the dynamism would make inventing classes on the fly
rather inconvenient.) There's a significant difference between
Javascript and Self, by the way: a Self object can have multiple
`parent' slots, consequently with a form of multiple inheritance, while
Javascript is limited to single inheritance (unless you fake it up).
However, multiple inheritance is something of a mess, as the original
starter of this thread found when he tried to document how to use it.
Python's object system certainly isn't ideal.
The main problem that I see is that dynamic delegation with `super' is
hideously inconvenient to use, which means that programmers will tend
towards C++'s static delegation instead.
The Python object construction protocol (__new__ and __init__) is
somewhat simplistic; constructing instances of multiply inherited
classes in general requires a somewhat complicated dance with *args and
**kw arguments -- and you lose the ability to reject unknown arguments
-- which again leads to programmers taking shortcuts.
Most of the rest of the object system seems pretty sound to me.
If you have real trouble writing documentation for a feature, it's
usually because the feature is badly designed.
It might be that it was misunderstood.
There seem to be two obvious ways of learning a programming language.
One is to try and interpret its concepts in terms of concepts that you
already understand. This works, but you end up having to `translate'
between the new language; if the translation is imperfect then you'll be
confused or frustrated. There's a constant temptation to force one's
existing conceptual framework onto the new language -- to use it as if
it worked just like something else one is more familiar with that
doesn't quite work `right'. The new language is `broken Blub with funny
syntax'.
The other is to try to understand it on its own terms. This is the
harder road that leads to mastery.
-- [mdw]