Python's "only one way to do it" philosophy isn't good?

Douglas Alan doug at alum.mit.edu
Mon Jun 25 16:35:18 EDT 2007


Alexander Schmolck <a.schmolck at gmail.com> writes:

> Douglas Alan <doug at alum.mit.edu> writes:

>>> Python has built-in abstractions for a few container types like
>>> lists and dicts, and now a new and more general one (iterators), so
>>> it's the next level up.

>> Common Lisp has had all these things for ages.

> Rubbish. Do you actually know any common lisp?

Yes, though it's been quite a while, and it was mostly on Lisp
Machines, which, at the time, Common Lisp was still being
standardized, and so Lisp Machine "Chine Nual" Lisp wasn't quite
Common Lisp compliant at the time.  Also, Lisp Machine Lisp had a lot
of features, such as stack groups, that weren't put into Common Lisp.
Also, my experience predates CLOS, as at the time Lisp Machines used
Flavors.

Most of my Lisp experience is actually in MacLisp (and Ulisp and
Proto, neither of which you've likely heard of).  MacLisp was an
immediate precursor of Common Lisp, and didn't have a standard object
system at all (I rolled one myself for my applications), but it had
the Loop macro and if I recall correctly, the MacLisp Loop macro
(which was nearly identical to the Chine Nual Loop macro, which I
thought was ported rather unsullied for Common Lisp).  In any case,
IIRC, there were hooks in the Loop macro for dealing with iterators
and I actually used this for providing an iterator-like interface to
generators (for Lisp Machines) that I coded up with macros and stack
groups.

It may be that these hooks didn't make it into the Common Lisp Loop
macro, or that my memory of what was provided by the macro is a little
off.  What's not off, is that it was really easy to implement these
things, and it wasn't like I was some sort of Lisp guru -- I was just
an undergraduate student.

I will certainly admit that Lisp programmers at the time were (and
likely still are) much more enamored of mapping functions than of
iterators.  Mapping functions certainly get the job done as elegantly
as iterators most of the time, although I would agree that they are
not quite so general.  Of course, using generators, I was easily able
to make a converter that would take a mapping function and return a
corresponding iterator.

Scheme, on, the other hand, at least by idiom, has computation
"streams", and streams are equivalent to iterators.

> There is precisely no way to express
>
>     for x in xs:
>         blah(x)

The canonical way to do this in Lisp would be something like:

   (mapcar (lambda (x) (blah x))
           xs)

Though there would (at least in MacLisp) be a differently named
mapping function for each sequence type, which makes things a bit less
convenient, as you have to know the name of the mapping function
for each type.

> or
>     x = xs[key]

I'm not sure what you are asserting?  That Common Lisp doesn't have
hash tables?  That's certainly not the case.  Or that it doesn't
provide standard generic functions for accessing them, so you can
provide your own dictionaries that are implemented differently and
then use exactly the same interface?  The latter I would believe, as
that would be one of my criticisms of Lisp -- although it's pretty
cool that you can load whatever object system you would like (CLOS
being by far the most common), it also means that the core language
itself is a bit deficient in OO terms.

This problem would be significantly mitigated by defining new
standards for such things in terms of CLOS, but unfortunately
standards change unbearably slowly.  There are certainly many
implementations of Lisp that solve these issues, but they have a hard
time achieving wide adoption.  A language like Python, which is
defined by its implementation, rather than by a standard, can move
much more quickly.  This debate though is really one more of
what is the best model for language definition, rather than one on
what the ideal language is like.

|>oug



More information about the Python-list mailing list