some random reflections of a "Python newbie": (2) language issues

Alex Martelli alex at magenta.com
Thu Dec 9 09:08:50 EST 1999


As I said in my other recent post...:

Alex Martelli <alex at magenta.com> wrote in message news:82o0to$6eq$1 at serv1.iunet.it...
> I've started playing with Python (starting with a strong
> background in C++, Perl, and sundry other matters),
> and I would like to share a few reflections, in the hope
> that I'll receive help on some of them, perhaps stimulate
> useful action with others, and maybe (through either
> my reflections, or, more likely, ensuing debate) be of
> some help to other newbies, too.
> 
> (Btw, my newsfeed's flaky -- if it were possible to cc
> me on any reply posts, I'd be grateful -- TIA!)
> 
> Please consider "IMHO"'s to be liberally inserted in
> what follows, of course!-).  

I'm continuing with numbered points from 3, since
points 1 and 2 I made in the other post.


3. "dictionary locking" in lieu of declarations

Some of us are into the "bondage and discipline"
style of programming -- we really want whatever
language engine we're using to diagnose as many
of our errors as it can, as soon as it can.  Perl and
Visual Basic started out even freer than Python,
regarding variable declarations, but now they
have -w, "use strict", and "Option Explicit", to help
those of us who are addicted to this - optionally,
of course, so freer spirits lose nothing by this.

Python is, well, halfway there -- it WILL tell me,
if I mis-spell a variable name in an expression;
however, it will NOT help me in any way, if my
mis-spelling is on the left-hand side of an
assignment statement.

The asymmetry is somewhat unpleasant, and
there is no support for our preferred style.

One idea I came up with, which could help
matters a bit, I think, and appears to be more
in the spirit of Python, than "declarations":
what if I could *LOCK* a dictionary, any
dictionary, including, of course, those where
variable names are kept for the various scopes;
so that any attempt to _add a new entry_ to the
dictionary would raise an exception.

This way, those of us who choose to, could
program in this style: start by "initializing",
e.g. an instance of a class in __init__, by
assigning initial values to all of its variables;
then, self.__dict__.lock(1), and I'd be all
set -- no further instance variables nor
methods could be "accidentally" added to
self any more (until, of course, I unlocked
its dictionary once more, presumably with
self.__dict__.lock(0) -- maybe in some
exception handler for the exception raised
by writing a locked dictionary, etc).

Thinking along these lines, in some cases I
could use a _stronger_ form of locking, one
roughly equivalent to C++'s "const", where,
not just creating new entries in a dictionary,
but even attempting to change what one of
them refers to, would also raise exceptions.
Maybe .lock(2), etc.

Given Python's powers of "introspection", I
bet some prototype for this could already be
hacked up, by subclassing the dictionary and
playing with __getattr__, __setattr__, and
__delattr__ -- but, as a newbie, I'm somewhat
reluctant to start along this path myself, in
particular since these dictionaries seem to be
somewhat "magical" (a much beloved term in
Perl, of course, not in Python...:-).  But that is
part of my motivation for posting this here --
if somebody can show me how to make my
dictionaries behave this way, I can play with
it and see if it is as useful as I now think.


4. why can't I overload "in" to have the
    expected semantics and maybe be fast...?

"if a in X:" and "for a in X:" will now both
give errors unless X is a sequence.  But
it would seem much more useful, elegant,
natural, polymorphic, and whatever other
buzzwords you desire, if there was some
__whatever__ method, or methods, that
I could overload on my object X, to make
these operations work, without wanting to
make X a sequence (besides, for the
"if a in X" case, I could give my true/false
answer much faster than the currently
rigid linear-iteration semants of "in"...!).

It's a pity to have to write, say,
    if X.hasElement(a):
rather than the natural
    if a in X
and it's a net loss of polymorphism, without
any compensating gain that I can see.

The way I envision this -- if X chooses to
implement a method __contains__, then,
for an "a in X" test, that method is called,
with a as an argument, and its return
value is taken as the test's result.  If X
has no such method, then we're back to
the current semantics of "if a in X", i.e.,
X must be a sequence, etc etc.


Regarding the
    for a in X:
case, the point is that I can well have a
class X such that linear iteration on it is
natural and smooth, while the random
addressing demanded by being a sequence
(a much stronger demand -- like being
a random iterator, rather than an input
iterator, in C++...) is inappropriate -- i.e.
where I can easily get the "next" item,
but not the "N-th item" for arbitrary N
without a large amount of work.

The way I envision this -- if X chooses to
implement a method __enum__, then,
that method must return an object which
implements methods such as __current__
(returning the current element in the
iteration) and __advance__ (returning
false if at end, else stepping forward) --
this is more flexible than requiring X
itself to implement such methods, of course,
because we must support nested loops
    for a in X:
        for b in X:
            # etc, etc
just as the current semantics do.


This one, I cannot see (being a newbie)
how to prototype in Python-as-it-stands
(not with the needed polymorphism, and
good performance, etc, which are the
whole point of the suggestion:-).



OK, enough for now, I think... I will
highly appreciate any feedback in this
matter (if its contents are "we don't
need this junk", I would further much
appreciate being explained _why_ we
don't need it -- e.g., why must there be
forever an asymmetry between reading
and writing, or, why is it right and proper
that in be always O(N) even when applied
to a RHS that wouldn't need it to be, etc).


Alex





More information about the Python-list mailing list