Python's simplicity philosophy (was Re: reduce()--what is it good for?)

Alex Martelli aleax at aleax.it
Tue Nov 11 12:09:01 EST 2003


Robin Becker wrote:
   ...
>>Python's essence is simplicity and uniformity.  Having extra features
>>in the language and built-ins runs directly counter to that.
> 
> no disagreement, reduce is in line with that philosophy sum is a
> shortcut and as others have said is less general.

'sum' is _way simpler_: _everybody_ understands what it means to sum a
bunch of numbers, _without_ necessarily having studied computer science.

The claim, made by somebody else, that _every_ CS 101 course teaches the
functionality of 'reduce' is not just false, but utterly absurd: 'reduce',
'foldl', and similar higher-order functions, were not taught to me back when
_I_ took my first university exam in CS [it used Fortran as te main
language], they were not taught to my son in _his_ equivalent course [it
used Pascal], and are not going to be taught to my daughter in _her_
equivalent course [it uses C].  Google for "CS 101" and convince yourself
of how utterly absurd that claim is, if needed -- how small is the
proportion of "CS 101" courses that teach these subjects.

Python's purpose is not, and has never been, to maximize the generality
of the constructs it offers.  For example, Ruby's hashes (and, I believe,
Perl's) are more general than Python's dicts, because in those hashes
you can use arbitrary mutable keys -- e.g., arrays (Ruby's equivalent of
Python's lists), strings (which in Ruby are mutable -- more general than
Python's strings, innit?), etc.  Python carefully balances generality,
simplicity, and performance considerations.  Every design is a series of
compromise decisions, and Python's design is, in my opinion, the best
one around (for my purposes) because those compromises are struck with
an _excellent_ batting average (not perfectly, but better than any other
language I've ever studied, or designed myself).  The underlying idea
that there should preferably be ONE obvious way to express a solution
is part of what has kept Python so great as it evolved during the years.


>>> The whole 'only one way to do it' concept is almost certainly wrong.
>>
>>Bingo!  You disagree with the keystone of Python's philosophy.  Every
>>other disagreement, quite consequently, follows from this one.
> 
> not so, I agree that there ought to be at least one way to do it.

But not with the parts that I quoted from the "spirit of C", and I
repeat them because they were SO crucial in the success of C as a
lower-level language AND are similarly crucial in the excellence of
Python as a higher-level one -- design principles that are *VERY*
rare among computer languages and systems, by the way:

    Keep the language small and simple.

    Provide only one way to do an operation.

"Only one way" is of course an _ideal_ goal (so I believe the way
it's phrased in Python, "preferably only one obvious way") -- but
it's a guiding light in the fog of languages constructed instead
according to YOUR completely oppposite goal, and I quote you:

    There should be maximal freedom to express algorithms.

Choose just about every OTHER language on Earth, and you'll find
it TRIES (with better or worse results depending on how well or
badly it was designed, of course) to meet your expressed goal.

But NOT Python: you're using one of the _extremely few_ languages
that expressly do NOT try to provide such "maximal freedom", that
try instead to stay small and simple and provide (preferably)
only one (obvious) way to do an operation.  Your choice of language
is extremely peculiar in that it _contradicts_ your stated goal!

>>Want "maximal freedom to express algorithms"?  You can choose among
> 
> ... you may be right, but I object to attempts to restrict my existing
> freedoms at the expense of stability of Python as a whole.

Nobody restricts your existing freedom of using Python 2.3.2 (or
whatever other release you prefer) and all of its constructs and
built-ins; nobody ever proposed retroactively changing the license
to do that (and I doubt it could be done even if anyone wished!).

But we're talking about Python 3.0, "the point at which backwards
compatibility will be broken" -- the next _major_ release.  To quote
Guido, in 3.0 "We're throwing away a lot of the cruft that Python has
accumulated."  After a dozen years of backwards compatible growth,
Python has a surprisingly small amount of such cruft, but it definitely
does have some.  Exactly _what_ qualifies as 'cruft' is not yet decided,
and it won't be for quite a while (Guido thinks he won't do 3.0 until
he can take PSF-financed time off to make sure he does it right).  But
there is no doubt that "reduce feature duplication" and "change rules
every so slightly to benefit optimization" _are_ going to be the
themes of 3.0.

Python can't keep growing with great new ideas, _AND_ still be a
small and simple language, without shedding old ideas that do not
pull their weight any more, if they ever did.  Check out, e.g.,
the "python regrets" talk of well over a year ago, 
  http://www.python.org/doc/essays/ppt/regrets/PythonRegrets.ppt
to see that lambda, map, filter, and reduce are all among those
regrets -- things that Guido believe he never should have allowed
in the language in the first place.  E.g., and I quote from him:

"""
reduce()
    nobody uses it, few understand it
    a for loop is clearer & (usually) faster
"""

and that was way BEFORE sum took away the vast majority of reduce's
use cases -- so, guess how he may feel about it now...?

One of Python's realities is that _Guido decides_.  Not without lots
of pressure being put on him each and every time he does decide, of
course -- that's part of why he doesn't read c.l.py any more, because
the pressure from this venue had gotten way excessive.  Of course,
he's going to be pressured on each and every one of the items he
mentions in detail in the "regrets" talk and more summarily in the
Python 3.0 "State of the Python Union" talk.  But I'm surely not the
only one convinced that here, like in (by far) most difficult design
decisions in Python's past, he's on the right track.  Python does
need to keep growing (languages that stop growing die), but it must
not become big, so it must at long last lose SOME of the accumulated
cruft, the "feature duplication".

I'll deeply regret, come Python 3.0, not being able to code
    "if blah(): fleep()"
on one single like any more, personally.  And I may try to put on
pressure for a last-minute reprieve for my own pet "duplicated
feature", of course.  But in the end, if I use Python it's because
I believe Guido is a better language designer than I am (and that
most other language designers are), so I will accept and respect
his decisions (and maybe keep whining about it forevermore, as I
do for the "print>>bah,gorp" one:-).


>>But can't you let us have *ONE* language that's designed according
> 
> I am not attempting to restrict anyone or change anyone's programming
> style. I just prefer to have a stable language.

I think Python's stability is superb, but stability cannot mean that
there will never be a 3.0 release, or that the language will have to
carry around forever any mistaken decision that was once taken.  I'm
not advocating a "high level of churn" or anything like that: we have
extremely "sedate" and stable processes to gradually deprecate old
features.  But such deprecation _will_ happen -- of that, there is
most definitely no doubt.


Alex





More information about the Python-list mailing list