Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dijkstra on Python

10 views
Skip to first unread message

Al Vining

unread,
Aug 12, 2002, 7:44:08 PM8/12/02
to
Well, not really, but in his remarks[1] on what was to become Ada he did
say:
"""
I thought that it was a firm principle of language design -- out of
concern for programming as a human activity -- that in all respects
equivalent programs should have few possibilities for different
representation [...]. Otherwise completely different styles of
programming arise unnecessarily, thereby hampering maintainability,
readability and what have you. This requires from the language
designers the courage to make up their minds!
"""
which sounds a lot like "There should be one -- and preferably only one
-- obvious way to do it."

There must be something in the water in the Netherlands.

[1] http://www.cs.utexas.edu/users/EWD/ewd06xx/EWD660.PDF

--
Al.

James J. Besemer

unread,
Aug 12, 2002, 11:56:44 PM8/12/02
to

Al Vining [and many others] write:

> "There should be one -- and preferably only one
> -- obvious way to do it."

I have a problem with this particular particle of Python dogma.

My chief problem is that it's every bit as meaningless and ridiculous as
when Larry Wall promotes the "other" way of doing things.

All of Wall's ridiculous talk of postmodern languages notwithstanding, the
simple fact of the matter is that there IS more than one way to solve most
problems in most any modern programming language. Actually, when Wall et
al. boasts about Perl's "unique" ability in this regard, if you really read
the examples, at bottom, they're usually just saying there are different
ways to implement a solution. Fact of the matter, in most of their examples
Perl generally doesn't offer any benefit vs. Python.

E.g., consider the implementation of Sets in Python (or Perl). You could
use dictionaries (as many propose) or plain lists or bitmaps of big
numbers. If sets are truly gigantic you may want to use b-trees or a
persistent Zope DB. You probably would encapsulate the abstraction in a
class but that's not necessary for simple implementations. Even in C, you
have your choice of bitmaps, arrays of numbers or pointers to objects, or
higher order data structures -- only it's more work than in Python or Perl.

So, plainly, "there's more than one way" to solve most problems in any
modern programming language.

This minimalist philosophy does perhaps have some merit in, say, designing
the syntax of the language. E.g., Perl goes overboard IMO with the various
ways to test a condition:

if( x ){ y }
y if x;
x && y;
x || y;

... and who knows what all else. So Python can be viewed as superior to
Perl in this sense.

However, Python itself breaks its own rules at the low level; e.g. with

for
while
map, et al.
list comprehension

... Python offers at least 4 redundant ways to iterate over a collection.

Now, IMO this is a GOOD thing, not a bad one. Having a narrow variety of
choices for things like this is good for the programmer. Larry Wall makes a
small point in that productivity will be higher if the language already
provides the mechanism the programmer first thinks of or is most familiar
with.

With bigger problems, the variety of implementation choices increases
exponentially.

Thus, in practice, this particular rallying call is every bit as meaningless
as Perl's.

Regards

--jb

--
James J. Besemer 503-280-0838 voice
http://cascade-sys.com 503-280-0375 fax
mailto:j...@cascade-sys.com

Rob Andrews

unread,
Aug 13, 2002, 12:47:07 AM8/13/02
to
"James J. Besemer" <j...@cascade-sys.com> wrote in
news:mailman.1029211160...@python.org:

>
> Al Vining [and many others] write:
>
>> "There should be one -- and preferably only one
>> -- obvious way to do it."
>
> I have a problem with this particular particle of Python dogma.
>
> My chief problem is that it's every bit as meaningless and ridiculous
> as when Larry Wall promotes the "other" way of doing things.
>

<snip />


>
> Now, IMO this is a GOOD thing, not a bad one. Having a narrow variety
> of choices for things like this is good for the programmer. Larry
> Wall makes a small point in that productivity will be higher if the
> language already provides the mechanism the programmer first thinks of
> or is most familiar with.
>

<snip />


>
> Thus, in practice, this particular rallying call is every bit as
> meaningless as Perl's.
>

But isn't it equally valid to say that Python's rallying call is every
bit as meaningFUL as Perl's? I'd say so.

Each approach possesses merit, as you pointed out in your own post, and
the merit has been intentional in Python's case as in Perl's. While it is
wise to consider the limitations and proper context of each perspective,
the finding of such boundaries need not invalidate the design principles
themselves (or even the implementations in question).

...just my $.02 worth,
Rob Andrews
http://www.uselesspython.com

Jonathan Hogg

unread,
Aug 13, 2002, 2:58:47 AM8/13/02
to
On 13/8/2002 4:56, in article
mailman.1029211160...@python.org, "James J. Besemer"
<j...@cascade-sys.com> wrote:

> Al Vining [and many others] write:
>
>> "There should be one -- and preferably only one
>> -- obvious way to do it."
>
> I have a problem with this particular particle of Python dogma.
>
> My chief problem is that it's every bit as meaningless and ridiculous as
> when Larry Wall promotes the "other" way of doing things.

[...]


> So, plainly, "there's more than one way" to solve most problems in any
> modern programming language.

Of course, but the statement is frequently misread. It says that there
should be one *obvious* way to do it. The point is that the first solution
that occurs to you should be the same as the first solution that would have
occurred to another Python programmer.

Having done it the obvious way and not achieved the required solution by
whatever metric (perhaps performance), you should try doing something
another way.

It's quite possible that the obvious way that occurred to you is less
obvious to someone else because of differences in your and their experience.
Through discourse here, and things like the Python Cookbook, we tend towards
the same patterns of programming Python.

> However, Python itself breaks its own rules at the low level; e.g. with
>
> for
> while
> map, et al.
> list comprehension
>
> ... Python offers at least 4 redundant ways to iterate over a collection.

Depending on the purpose of the iteration, hopefully one of these will seem
the more obvious choice than the others. Do you find yourself spending much
time agonising over which to use?

I'd say the only ones that overlap in any great respect are map/filter and
list comprehensions. Arguably, list comprehensions are now considered the
more Pythonic solution.

> Now, IMO this is a GOOD thing, not a bad one. Having a narrow variety of
> choices for things like this is good for the programmer. Larry Wall makes a
> small point in that productivity will be higher if the language already
> provides the mechanism the programmer first thinks of or is most familiar
> with.

One problem that Python attempts to aid is not a programmer's initial
productivity in writing the code, but his/her or another's subsequent
productivity in maintaining it.

Perl usage tends to be so idiosyncratic that I've known Perl programmers who
couldn't read their *own* code after a while, let alone the difficulty in
reading someone else's Perl.

> Thus, in practice, this particular rallying call is every bit as meaningless
> as Perl's.

Which is perhaps why The Zen of Python should be filed under "humour" ;-)

Jonathan

Robin Becker

unread,
Aug 13, 2002, 4:12:40 AM8/13/02
to
In article <mailman.1029211160...@python.org>, James J.
Besemer <j...@cascade-sys.com> writes
......

>
>E.g., consider the implementation of Sets in Python (or Perl). You could
>use dictionaries (as many propose) or plain lists or bitmaps of big
>numbers. If sets are truly gigantic you may want to use b-trees or a
>persistent Zope DB. You probably would encapsulate the abstraction in a
>class but that's not necessary for simple implementations. Even in C, you
>have your choice of bitmaps, arrays of numbers or pointers to objects, or
>higher order data structures -- only it's more work than in Python or Perl.
>
>So, plainly, "there's more than one way" to solve most problems in any
>modern programming language.
.....
as another example one only has to consider the dictator's paper on
python optimisation http://www.python.org/doc/essays/list2str.html which
has no fewer than 7 ways to do the same thing. The zen of Python is
often pretty meaningless.
--
Robin Becker

James J. Besemer

unread,
Aug 13, 2002, 4:57:00 AM8/13/02
to

Jonathan Hogg wrote:

> "James J. Besemer"<j...@cascade-sys.com> wrote:
>
> > So, plainly, "there's more than one way" to solve most problems in any
> > modern programming language.
>
> Of course, but the statement is frequently misread. It says that there
> should be one *obvious* way to do it. The point is that the first solution
> that occurs to you should be the same as the first solution that would have
> occurred to another Python programmer.
>
> Having done it the obvious way and not achieved the required solution by
> whatever metric (perhaps performance), you should try doing something
> another way.
>
> It's quite possible that the obvious way that occurred to you is less
> obvious to someone else because of differences in your and their experience.
> Through discourse here, and things like the Python Cookbook, we tend towards
> the same patterns of programming Python.

Nah, this all is just a pipe dream. Sharing and reusing some idioms is a far cry
from always having "one obvious way to do it."

The saying is clearly a retort in opposition to Perl's "more than one way". But
in that sense it's intellectually dishonest because the way Perl users usually use
the phrase (e.g., dictionaries vs. lists vs. bitmaps), it, in all fairness,
applies equally well to Python.

Else, what is the "obvious" solution for Sets? Depends on size, speed, mutability
of elements, etc. Once you have all the auxiliary requirements, they may lead you
to one solution over the others, but at the level where choices begin to become
meaningful, the same alternatives and trade-offs are available in most languages.

Look at many of the newbie questions on this list: the answers include several
different variations even on trivial problems.

> Depending on the purpose of the iteration, hopefully one of these will seem
> the more obvious choice than the others. Do you find yourself spending much
> time agonising over which to use?

No, of course not. I'm the one saying multiple alternatives (to a point) are a
good thing, not something to be ashamed of.

> I'd say the only ones that overlap in any great respect are map/filter and
> list comprehensions. Arguably, list comprehensions are now considered the
> more Pythonic solution.

I think the recent addition of list comprehension (wholly redundant with the
others and slowest of the bunch) is a glaring example of "more than one way to do
it." You can forgive the earlier forms for historical reasons but comprehension
are pure redundancy. I see them more directly redundant with for/if.

That doesn't make them bad. But including them DOES violate the rule. And the
only reason for them that I can see is they're a cute and novel "another way to do
it."

> One problem that Python attempts to aid is not a programmer's initial
> productivity in writing the code, but his/her or another's subsequent
> productivity in maintaining it.

I submit if Python did not help people's initial productivity hardly anybody would
use it. Python DOES help greatly with initial productivity. This conclusion is
consistent with the many testimonials on this list.

That's not to say Python's simple and uniform syntax doesn't aid maintainability.
Or that initial productivity was a language design goal. Only that it happens to
be true and it's a good thing.

> Perl usage tends to be so idiosyncratic that I've known Perl programmers who
> couldn't read their *own* code after a while, let alone the difficulty in
> reading someone else's Perl.

Yeah, Perl sucks. It's cryptic syntax certainly hurts maintainability. For me,
it's so screwy that it even hinders initial development. But that's not the
point. I"m not saying Perl is good as or better than Python. I hate Perl.

The only common point between the two languages that I was pressing is that
"there's more than one way to do it" applies equally well to both languages far
better than "only one obvious way" applies to Python.

I only disagree with the the dogma. I disagree in part because it's not true and
in part because "sound bites" and slogans bring the discussion down to Larry
Wall's level.

> > Thus, in practice, this particular rallying call is every bit as meaningless
> > as Perl's.
>
> Which is perhaps why The Zen of Python should be filed under "humour" ;-)

That's a very good point I had overlooked.

I guess it would be easier for me to laugh it off if you and others didn't seem to
believe it so sincerely.

And I don't want to make too big of a deal of this. It's just a minor nit with me
anyway.

holger krekel

unread,
Aug 13, 2002, 4:48:19 AM8/13/02
to
James J. Besemer wrote:
> Al Vining [and many others] write:
>
> > "There should be one -- and preferably only one
> > -- obvious way to do it."
>
> So, plainly, "there's more than one way" to solve most problems in any
> modern programming language.

These two statements are not strongly contradicting each other.

In fact, i concur that python usually offers one *obvious*
way to do something and that's a good thing. Just because
there is an infinite set of alternatives (with almost
every language) doesn't limit the validity of the quoted
statement.

just my 2ec,

holger

Carl Banks

unread,
Aug 13, 2002, 6:13:42 AM8/13/02
to
James J. Besemer wrote:
[snip]


I'm sorry, chief, but you are seriously missing the point here.

First of all, the word "always" is not part of the motto, although you
seem to be arguing under the premise that it is. Try importing "this"
for the canonical (I suppose) version of the statement: "There should
be one-- and preferably only one --obvious way to do it."


When Pythonistas say "there should be only one obvious way to do it,"
we are not saying, "this is how Python is." We are saying, "this is
what our programming philosophy is."

When Perlochists say "there's more than one to do it," they are not
saying, "this is how Perl is." They are saying, "this is what our
programming philosophy is."


The fact is, both mottos can apply to both languages. There certainly
is more than one way to do it in Python.

And, even in Perl, there is often only one obvious way to do it. For
example, take a look at the perlsyn manpage, in the section called
"Basic BLOCKs and Switch Statements." The section exemplifies several
different ways to do switch statements, but guess what? There's only
one obvious way (and naturally it was the way that was discouraged).

And that really governs the language design of Python. It means that
all sinewy little tricks are not strewn through the syntax. Perhaps a
better motto would be, "if there's an obvious way to do it, there
doesn't need to be another way." Or maybe, "you should do it the
obvious way." But those, of course, don't contrast as well with
Perl's motto.


And finally, whether you want to believe it or not, when Pythonistas
say "there should be only one obvious way to do it," we really are
talking about common idioms like for loops and switch statements. No
one is talking about sets when they say it.

--
CARL BANKS
http://www.aerojockey.com

Roy Smith

unread,
Aug 13, 2002, 6:53:21 AM8/13/02
to
"James J. Besemer" <j...@cascade-sys.com> wrote:
> This minimalist philosophy does perhaps have some merit in, say, designing
> the syntax of the language. E.g., Perl goes overboard IMO with the various
> ways to test a condition:
>
> if( x ){ y }
> y if x;
> x && y;
> x || y;

I agree 105% that having an alternative form of the "if" statement in
perl is utterly brain-dead. It's different for the sake of being
different, and adds no value that I can see. But, if you're going to
pick on perl's "x || y" idiom, keep in mind that you *can* do exactly
the same thing in python:

>>> 0 or sys.stdout.write('got here\n')
got here
>>> 1 or sys.stdout.write('got here\n')
1

it's just a side-effect of a perfectly common and reasonable feature
(short-circuit evaluation) which many languages share. The big
difference between perl and python WRT this idiom is mostly cultural.
In the perl community, "defined(foo) || die ('no foo')" is considered
standard usage. In the python community, you'd probably get shouted
down if you tried to write the above as anything other than:

>>> try:
... foo
... except NameError:
... sys.stderr.write ('no foo\n')
... sys.exit(1)
...
no foo

Peter Hansen

unread,
Aug 13, 2002, 7:38:09 AM8/13/02
to

Zen in general is often pretty meaningless, but it's still a wind
with no clouds in the sky.

-Peter

James J. Besemer

unread,
Aug 13, 2002, 7:49:01 AM8/13/02
to

Roy Smith wrote:

> I agree 105% that having an alternative form of the "if" statement in
> perl is utterly brain-dead. It's different for the sake of being
> different, and adds no value that I can see.

I think the mistake was in originally always requiring braces, instead
of following C where they're optional for a single statement. Parsing
such constructs is not brain surgery but evidently it was beyond the
ability of Larry Wall at the time (his claims of world class computer
linguist notwithstanding). Too, superficially it sounds like one of those
simplifications that are quite reasonable. However, putting braces around
single statements is tedious and error prone (as I'm sure all Pythonistas
will agree). Instead of correcting the first mistake I surmise that Mr. Wall
(typically) patched it with a second, bigger wart, the "x if y;" form.

> But, if you're going to
> pick on perl's "x || y" idiom, keep in mind that you *can* do exactly
> the same thing in python:

I understand and in including the idiom in a list of where Perl goes
"overboard" I do not mean to fully condemn it. I include it only to
show that the list is long.

However, I'd point out that it's not exactly the same in the two
languages, as in Perl you can say

open( foo ) || print "couldn't open $foo\n";

while in Python such usage is strictly limited to expressions.
Also, as you point out, it's culturally taboo.

I agree that in many instances the bigger differences (beyond mere
syntax, where Perl truly suffers) are cultural rather than actual.
In fact that was a central point of my 'nit pick' about the slogan.

James J. Besemer

unread,
Aug 13, 2002, 9:45:47 AM8/13/02
to

Carl Banks wrote:

> James J. Besemer wrote:
> [snip]
>
> I'm sorry, chief, but you are seriously missing the point here.
>
> First of all, the word "always" is not part of the motto, although you
> seem to be arguing under the premise that it is. Try importing "this"
> for the canonical (I suppose) version of the statement: "There should
> be one-- and preferably only one --obvious way to do it."
>
> When Pythonistas say "there should be only one obvious way to do it,"
> we are not saying, "this is how Python is." We are saying, "this is
> what our programming philosophy is."

I hear what you're saying. To hold it up as an ideal is one thing.
But the ideal seems so far from reality that it really strikes me as
somewhat ridiculous when somebody uses the slogan.

And not all people on this list who echo the slogan seem to take it
the way you say. Mr Hogg's reply seems to include a stronger
interpretation (everybody thinks of the same solution first).
And I've gotten in arguments here where somebody maintained
that Pythonistas' productivity materially suffered if anybody's code
strayed even in the most insignificant fashion from nits in PEP 8
(the overriding "clarity" escape clause notwithstanding).

Lordy, save me!

> When Perlochists say "there's more than one to do it," they are not
> saying, "this is how Perl is." They are saying, "this is what our
> programming philosophy is."

No. They're praising PERL for having so many features. Often
they're furthermore praising a particular developer for coming up
with a solution the first person had never thought of.

In any case, the Perl motto is just plain dumb. Of course there's
more than one way to do it, so what's the bloody point?

For Python to respond in kind cheapens the discourse. It lowers
us to their level. It's a cute sound bite and not bad rhetoric but we'd
do better to rise above it and for the most part simply ignore Perl
altogether.

> The fact is, both mottos can apply to both languages. There certainly
> is more than one way to do it in Python.

This was my main point, though I don't agree it's a symmetrical
relationship. Perl's motto is more applicable to both languages
than Python's is to either.

> And, even in Perl, there is often only one obvious way to do it.

Sometimes, perhaps with enough context, about as often as in
Python or C or C++.

E.g., process all the lines in a file. With the recent addition of
iterators, "for line in file:" is the pretty obvious choice,
analogous to Perl's "while(<>){".

Oh, wait. What about file.read() and file.readlines()? Oops. 3
ways to process a file and probably more. Seems I can only
come up with bad examples.

> And that really governs the language design of Python. It means that
> all sinewy little tricks are not strewn through the syntax.

That's fair. The little tricks, puns and arcane punctuation are
Perl's weakest point and where it contrasts the most with Python.
On the other hand, a lot of Perl's arcane syntax is simply piss
poor language design, not really features. There's absolutely
no excuse for having the programmer manually track $ and @
"context" in order to get lists.

In any case, you are correct in that The Argument has been
used (for better or for worse) to reject certain proposed
features, such as do-while, "++", "?:", while-getdata, assignment
operators, etc. My problem is the philosophy is applied inconsistency.

E.g., do-while seems perfectly legitimate and innocent and, given
the present scope of Python, it hardly could be considered a big
change. It's not uncommon to want to do something at least once
and repeat depending on a trailing test. It's not overly inventive,
as many languages include the feature. Hell, even Pascal has
repeat-until. Having an explicit syntax for this fairly common
control flow seems a no-brainer and yet it's been excluded on
"one way" terms (and evidently with great prejudice, based
on some of the comments I've heard on this list). And yet,
out of the blue, we get list comprehension, which solves no
new problem and is slower than the pre-existing alternatives.
I fail to see how it adds clarity (arguments to that end
notwithstanding), as the inventive syntax and semantics are
going to be unfamiliar to just about everybody, novice and
experienced programmer alike.

So, in practice, "one way" is often just a shield for somebody's
personal prejudice. Mere rationalization.

> And finally, whether you want to believe it or not, when Pythonistas
> say "there should be only one obvious way to do it," we really are
> talking about common idioms like for loops and switch statements. No
> one is talking about sets when they say it.

Then perhaps the motto should be "there's less than 5 ways to do it!" ;o)

Seriously, every time I think I maybe found an example, I then realize
there are 3 or 4 alternatives. But then, I've only been using Python
regularly for about 4 years now, so what do I know?

So. I challenge y'all to educate me. Instead of arguing philosophy,
come up with a concrete list of example problems for which Python
offers only one obvious solution (and of course show the solution).
If this is such a central part of the language design and of the
development community's philosophy, y'all should be able to
whip out, say, 50 or 100 examples off the top of your head.
Note we're confined to "common idioms like for loops and
switch statements" (not higher level problems that would
be even less likely to have unique solutions).

Let's keep this under the current subject and put

UNIQUE PROBLEM/SOLUTION

at the top of your message.

I've heard the arguments, now show me the data! I'm genuinely
curious to see how many of you who talk the talk here can
walk the walk -- and if there really is anything at all for which
Python has a genuinely obvious and unique solution.

If we get a good list going, I'll format it into a nice "howto" and
submit it to the powers that be for the benefit of future Pythonites.

bru...@tbye.com

unread,
Aug 13, 2002, 11:31:59 AM8/13/02
to
On Tue, 13 Aug 2002, James J. Besemer wrote:

> > I'm sorry, chief, but you are seriously missing the point here.
> >
> > First of all, the word "always" is not part of the motto, although you
> > seem to be arguing under the premise that it is. Try importing "this"
> > for the canonical (I suppose) version of the statement: "There should
> > be one-- and preferably only one --obvious way to do it."
> >
> > When Pythonistas say "there should be only one obvious way to do it,"
> > we are not saying, "this is how Python is." We are saying, "this is
> > what our programming philosophy is."
>
> I hear what you're saying. To hold it up as an ideal is one thing.
> But the ideal seems so far from reality that it really strikes me as
> somewhat ridiculous when somebody uses the slogan.
>
> And not all people on this list who echo the slogan seem to take it
> the way you say. Mr Hogg's reply seems to include a stronger
> interpretation (everybody thinks of the same solution first).
> And I've gotten in arguments here where somebody maintained
> that Pythonistas' productivity materially suffered if anybody's code
> strayed even in the most insignificant fashion from nits in PEP 8
> (the overriding "clarity" escape clause notwithstanding).

I don't take that saying too literally but just as a peek into a language
designer's general philosophy. It applies less and less as you move
farther up the chain from implementation to design to architecture.

For example, it obviously doesn't mean that in Python there's only one
obvious way to build a GUI or create a distributed messaging system.
Instead it applies to that final step of translating pseudocode/ideas into
Python code, it's the notion that that step is hopefully as painless,
straightforward, and unambiguous as possible. This ties into the common
experience that if you don't know how to express something in Python, your
best guess is often right. :-)

-Dave


Jonathan Hogg

unread,
Aug 13, 2002, 12:36:32 PM8/13/02
to
On 13/8/2002 14:45, in article
mailman.1029246560...@python.org, "James J. Besemer"
<j...@cascade-sys.com> wrote:

> E.g., process all the lines in a file. With the recent addition of
> iterators, "for line in file:" is the pretty obvious choice,

Heh heh heh. It seems you've proved my point.

Like I said, the argument is not that there is only one way to do it, but
that there should be an obvious way to do it.

Further to this, there should "preferably" be only one obvious way to do it.
However, this does not preclude there being *more* than one obvious way to
do it.

But there should certainly never be *no* obvious way to do something.

With Zen, the more you read it, the less it means what you thought it meant.
Of course, in the end it may no longer mean anything at all ;-)

Jonathan

Hamish Lawson

unread,
Aug 13, 2002, 2:15:05 PM8/13/02
to
Al Vining remarked on some similarities in language-design philosophy
between Dijkstra and Guido:

> There must be something in the water in the Netherlands.

Moreover both were at different times at the Mathematisch Centrum in
Amsterdam(now Centrum voor Wiskunde en Informatica).


Hamish

Carl Banks

unread,
Aug 13, 2002, 4:52:23 PM8/13/02
to
James J. Besemer wrote:

>
> Carl Banks wrote:
>
>> When Perlochists say "there's more than one to do it," they are not
>> saying, "this is how Perl is." They are saying, "this is what our
>> programming philosophy is."
>
> No. They're praising PERL for having so many features.

Well, yes. Literally.


> Often
> they're furthermore praising a particular developer for coming up
> with a solution the first person had never thought of.
>
> In any case, the Perl motto is just plain dumb. Of course there's
> more than one way to do it, so what's the bloody point?

Because it's their philosophy. They know very well that there is more
than one way to do it in other languages. When they say, "there's
more than one way to do it," they might be literally praising Perl,
but the underlying subtext is that "having more than one way to do it
is a great thing." And when you realize this, then their motto starts
making bloody sense.

IOW, you need to stop taking these statements so literally, and think
about what they really mean.


> For Python to respond in kind cheapens the discourse. It lowers
> us to their level. It's a cute sound bite and not bad rhetoric but we'd
> do better to rise above it and for the most part simply ignore Perl
> altogether.

Well, I don't take these statements as literally as you do, and I
don't think their underlying meaning is cheap.


>> The fact is, both mottos can apply to both languages. There certainly
>> is more than one way to do it in Python.
>
> This was my main point, though I don't agree it's a symmetrical
> relationship. Perl's motto is more applicable to both languages
> than Python's is to either.

Well, my point was that, since both mottos can apply to both
languages, they aren't meant to describe the languages, per se.

We both agree that both statements apply to both language, and not in
the same degree. There are two possibilities: that the utterers of
these mottos are "intellectually dishonest" and "cheap" because they
know both mottos apply to both languages yet they utter it as if it
applies uniquely to their own language; or that the motto isn't
intended so much as a description of the languages, but a description
of programming philosopiess (and face it, the mottos don't both apply
equally to Perl and Python community philosophies).

You appear to believe the former possibility; I believe the latter.


[snip]

>> And finally, whether you want to believe it or not, when Pythonistas
>> say "there should be only one obvious way to do it," we really are
>> talking about common idioms like for loops and switch statements. No
>> one is talking about sets when they say it.
>
> Then perhaps the motto should be "there's less than 5 ways to do it!" ;o)
>
> Seriously, every time I think I maybe found an example, I then realize
> there are 3 or 4 alternatives. But then, I've only been using Python
> regularly for about 4 years now, so what do I know?
>
> So. I challenge y'all to educate me. Instead of arguing philosophy,
> come up with a concrete list of example problems for which Python
> offers only one obvious solution (and of course show the solution).

You still don't get it. I will say it one last time: "There should be
one obvious way to do it" *is* philosophy. You might ignore the fact
that this statement has underlying subtext, but other people
understand this, and it's not ingenuous or wrong of us to use it in
this way.

The real meaning of "There should be one obvious way to do it" is that
the Python community values:
* Sticking to common idioms
* Avoiding the use of clever constructions
* Avoiding coding in a way that requires a reader to "decode" it, if
it can be avoided

...

It seems to me, James, that you are a down-to-earth, literal person.
Which is perfectly admirable. But you see, this motto is considered
Python Zen, and let's face it, Zen really isn't for down-to-earth,
literal people.

The motto is simply the Zen-like way of describing the philosophy of
the Python community. I suggest that, instead of trying to make an
issue out of it, you chaulk up the motto as one of those "cryptic,
backwards sayings that the head-in-the-clouds, Ecstacy-using, Zen
people think are cute."

Christopher A. Craig

unread,
Aug 13, 2002, 10:12:34 PM8/13/02
to
Robin Becker <ro...@jessikat.fsnet.co.uk> writes:

> as another example one only has to consider the dictator's paper on
> python optimisation http://www.python.org/doc/essays/list2str.html which
> has no fewer than 7 ways to do the same thing. The zen of Python is
> often pretty meaningless.

But only one of those ways (or maybe none of them) is the obvious
solution. Certainly you don't claim that you immediately thought of
f5 and f7 when you read the problem, or that if you were asked to
create a string from a list of ASCII values you would be thrown into a
conundrum about the merits of the various obvious solutions to the
problem.

At the time that paper was written, I would have considered f1 to be
the obvious solution. Unless I had some good reason for needing to
optimize, I never would have tried anything else. Now, having become
more one with Python, I would immediately write
"".join(map(chr, list)) without even thinking. That from is concise,
fast, and its meaning rather obvious.

It is important to keep in mind that it is the Zen of Python, not the
Python Feature List, or the Cardinal Rules of Python Programming. Two
people listening to a waterfall may not hear the same thing.

--
Christopher A. Craig <list-...@ccraig.org>
"Beware of bugs in the above code; I have only proved it correct, not
tried it." Donald Knuth

James J. Besemer

unread,
Aug 14, 2002, 1:28:04 AM8/14/02
to

Carl Banks wrote:

> The motto is simply the Zen-like way of describing the philosophy of
> the Python community. I suggest that, instead of trying to make an
> issue out of it, you chaulk up the motto as one of those "cryptic,
> backwards sayings that the head-in-the-clouds, Ecstacy-using, Zen
> people think are cute."

Fair enough. ;o)

Greg Ewing

unread,
Aug 14, 2002, 2:26:42 AM8/14/02
to
Jonathan Hogg wrote:

> With Zen, the more you read it, the less it means what you thought it meant.


You mean you think it means something the first
time you read it?

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Greg Ewing

unread,
Aug 14, 2002, 2:22:07 AM8/14/02
to
Peter Hansen wrote:

> Zen in general is often pretty meaningless, but it's still a wind
> with no clouds in the sky.


Are you sure it's not a sound without one
hand clapping?

Robin Becker

unread,
Aug 14, 2002, 4:14:32 AM8/14/02
to
In article <mailman.102929120...@python.org>, Christopher
A. Craig <list-...@ccraig.org> writes
>Robin Becker <ro...@jessikat.fsnet.co.uk> writes:
......

>At the time that paper was written, I would have considered f1 to be
>the obvious solution. Unless I had some good reason for needing to
>optimize, I never would have tried anything else. Now, having become
>more one with Python, I would immediately write
>"".join(map(chr, list)) without even thinking. That from is concise,
>fast, and its meaning rather obvious.
....
well as a day to day thing your current prime choice is unusable since
it needs strings to be class objects and certainly won't work in a large
percentage of Python installations which are stuck at 1.5.2.

"There is only one way to do it until a better way comes along or until
a requirement changes or......."
--
Robin Becker

nnes

unread,
Aug 14, 2002, 7:19:53 AM8/14/02
to
"James J. Besemer" <j...@cascade-sys.com> wrote in message news:<mailman.1029211160...@python.org>...

> Al Vining [and many others] write:
>
> > "There should be one -- and preferably only one
> > -- obvious way to do it."
>
>
> However, Python itself breaks its own rules at the low level; e.g. with
>
> for
> while
> map, et al.
> list comprehension
>
> ... Python offers at least 4 redundant ways to iterate over a collection.
>
or lamda which seems to me like a special case of def. Or print which
is a special case of write() on the standard output. etc.

And the BDFL regrets it (specially read pages 3-5):

http://www.python.org/doc/essays/ppt/regrets/PythonRegrets.pdf

The problem is since Python is an evolving language it may take some
time until the BDFL (by analysing python code/patterns) finds the
preferable and obvious way to do it. To parafrase: The "preferable
only one way" may not be obvious at first unless you're Dutch, and
even then it is tricky :-). In the meantime we are experimenting with
different alternatives.

I can only hope that Python goes with the "less is more" aproach and
starts deprecating some of this stuff, instead of just adding new one,
so that newcomers will use "preferable only one way", making it easier
to read their programms.

A good example of this last is xreadlines which will be deprecated in
2.3 and will be replaced by: for line in file. This was more of an
performance issue in the old implementation than anything else. But a
lot of my code used it, because it was faster under 2.1. So now I will
actually having 2 ways to do the same depending on the Python version:
the 2.1 way and the more cleaned up way.

Hopefully the language will converge to cover 90% of the common tasks
at hand using obvious syntax, and these being the speed optimized ones
to encourage its usage.

I still prefer growing pains to no growth

Nestor

Peter Hansen

unread,
Aug 14, 2002, 7:41:25 AM8/14/02
to
Greg Ewing wrote:
>
> Peter Hansen wrote:
>
> > Zen in general is often pretty meaningless, but it's still a wind
> > with no clouds in the sky.
>
> Are you sure it's not a sound without one hand clapping?

I have *both* hands clapping, but I'm still not sure it's a sound.
When I tried deciding if it were a sound while clapping only one
hand, I fell off my chair.

-Peter

Steve Holden

unread,
Aug 14, 2002, 11:29:27 AM8/14/02
to
"nnes" <prue...@latinmail.com> wrote in message
news:d8778a53.02081...@posting.google.com...
Well, lots of stuff is due to be deprecated, but one of the problems is the
screams of horror that appear in this newsgroup whenever anything is changed
in a potentially non-backwards-compatible way.

> A good example of this last is xreadlines which will be deprecated in
> 2.3 and will be replaced by: for line in file. This was more of an
> performance issue in the old implementation than anything else. But a
> lot of my code used it, because it was faster under 2.1. So now I will
> actually having 2 ways to do the same depending on the Python version:
> the 2.1 way and the more cleaned up way.
>
> Hopefully the language will converge to cover 90% of the common tasks
> at hand using obvious syntax, and these being the speed optimized ones
> to encourage its usage.
>
> I still prefer growing pains to no growth
>

Me too. I'm hoping that the Python Business Foundation's work to provide
more stable, longer-lived, Python environments will allow the language to
keep changing without affecting whatever commercial success it's achieveing.

regards
-----------------------------------------------------------------------
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/pwp/
-----------------------------------------------------------------------

Christopher A. Craig

unread,
Aug 14, 2002, 3:06:04 PM8/14/02
to
Robin Becker <ro...@jessikat.fsnet.co.uk> writes:

> well as a day to day thing your current prime choice is unusable since
> it needs strings to be class objects and certainly won't work in a large
> percentage of Python installations which are stuck at 1.5.2.

Yeah, but I distribute very little of my code, which means I don't
care much about that. Given my normal set of requirements and my
understanding of the language, that is the one obvious solution.

--
Christopher A. Craig <list-...@ccraig.org>

"Sir, your remarks are repugnant to me, and I disagree with your viewpoints.
But I will defend to the death your right to express them." Voltaire

James J. Besemer

unread,
Aug 15, 2002, 7:12:44 AM8/15/02
to

Steve Holden wrote:

> Well, lots of stuff is due to be deprecated, but one of the problems is the
> screams of horror that appear in this newsgroup whenever anything is changed
> in a potentially non-backwards-compatible way.

(a) As Carl explained, the "one way" motto is fundamentally just a "cute
saying."

(b) I and others showed examples how in cases where when the underlying
philosophy is applied, it's applied inconsistently and capriciously.

(c) Nobody thus far presented a single example where there's only "one way"
to do something or where it provides any tangible, practical benefit.

All that, balanced with the tangible material hardship non-backwards-
compatible changes present for people trying to maintain existing software,
makes deprecating historic features a POINTLESS and STUPID exercise.
It should only be considered in rare, extreme cases e.g., where it's impossible
to add some significant new feature without breaking some old code. Even
then it should be avoided if there's any alternative.

Non-backwards-compatible changes force the existing installed base to update
their software or else eschew staying up to date with new releases of the
language.
Alternatively, the minority squeaky wheel that cares simply eschews those
features they feel would hinder the readability of their programs. One
alternative impacts practically everybody; the other hardly anybody.
The cost of leaving historic features in is virtually zero. The cost of taking
them out is literally incalculable.

The turmoil in simply arguing about what features to deprecate probably
would consume more energy than any potential "readability cost" savings
of removing them.

It's a Good Thing that the powers that be have generally refrained in the
past from indulging this silly prejudice. I hope they will continue to be
diligent in the future about not breaking old code.

> Me too. I'm hoping that the Python Business Foundation's work to provide
> more stable, longer-lived, Python environments will allow the language to
> keep changing without affecting whatever commercial success it's achieveing.

Non-backwards-compatible changes is a great way to disrupt the
spread of Python into commercial realms.

"Whadda ya mean we can't use the bug-fix version of Python
unless/until we rewrite the code??!!"

I was chided for taking the motto too literally and too seriously and yet
here, later in the same thread, it is cited as the reason to unnecessary
complicate life for the installed base.

It seems ridiculous even to have to defend this point of view.

Michael Hudson

unread,
Aug 15, 2002, 7:37:17 AM8/15/02
to
"James J. Besemer" <j...@cascade-sys.com> writes:

> Non-backwards-compatible changes is a great way to disrupt the
> spread of Python into commercial realms.
>
> "Whadda ya mean we can't use the bug-fix version of Python
> unless/until we rewrite the code??!!"

You do of course know that no bug-fix version of Python will remove a
feature, don't you?

If you said

"Whadda ya mean we can't use the NEW version of Python


unless/until we rewrite the code??!!"

I might have thought you had a point.

Cheers,
M.

--
Unfortunately, nigh the whole world is now duped into thinking that
silly fill-in forms on web pages is the way to do user interfaces.
-- Erik Naggum, comp.lang.lisp

James J. Besemer

unread,
Aug 15, 2002, 8:37:26 AM8/15/02
to

Michael Hudson wrote:

> You do of course know that no bug-fix version of Python will remove a
> feature, don't you?

How about the case where a non-upwards-compatible,
non-bug-fix release N is followed by a release N+1 that
fixes a bug which happened to be present in release N-1?

This would again leave the maintenance team using release
N-1 stuck between a rock and a hard spot -- without anyone
having violated the above rule.

The only reasonable policy is to never break old code
unless absolutely forced to.

Skip Montanaro

unread,
Aug 15, 2002, 10:27:50 AM8/15/02
to

jb> How about the case where a non-upwards-compatible, non-bug-fix
jb> release N is followed by a release N+1 that fixes a bug which
jb> happened to be present in release N-1?

If there is enough demand, someone will backport the patch to release N-1.M.
Bugs fixed in the 2.3 code base are routinely backported to the 2.2
maintenance branch.

--
Skip Montanaro
sk...@pobox.com
consulting: http://manatee.mojam.com/~skip/resume.html

Skip Montanaro

unread,
Aug 15, 2002, 9:43:13 AM8/15/02
to

James> (a) As Carl explained, the "one way" motto is fundamentally just
James> a "cute saying."

No it's not. You point to one or two examples where there are multiple ways
to do things and then generalize to say that the "one way" motto is nothing
more than PR speak. You fail to see all the times it's been applied
successfully because those proposed features never made it into the
language. Guido applies it routinely. If he didn't, I suspect we'd have a

do:
...
until: ...

or

repeat:
...
while: ...

construct (or some other variant), and maybe one or two ways to spell
"switch" (which I note even Perl doesn't have - I guess Guido's waiting for
Larry to bless it ;-) in the language by now. Both have been asked for many
times. In fact, there's even a PEP for a switch statement. I believe the
fact that you sometimes find overlapping language constructs can be
attributed to one of the following two reasons:

1. They overlap in some respects, but their natural "domains" really
don't. This applies to your for/while/list comprehension/map
example. BTW, you don't really need any of these iterative
constructs. After all, we have functions and the language supports
recursion. I say, let's get back to basics. ;-)

2. Language design being what it is (an art rather than a science) and
Guido's time machine notwithstanding, even the Dutch don't have a
crystal ball to look into the future to see what the perfect language
is. Generally, Guido's gotten it right. That's why so many of us
enjoy using Python. Still, he admits to the occasional weak moment
(lambda, for example). As Steve Holden pointed out, once in the
language, core features take a long time to get rid of. That's an
application of "practicality beats purity". If Guido deleted every
feature from the language as soon as he developed something better to
replace it, I suspect he and Tim might be the only people using
Python. It would be a very "pure" language, but not very
"practical".

Donn Cave

unread,
Aug 15, 2002, 12:59:37 PM8/15/02
to
Quoth "James J. Besemer" <j...@cascade-sys.com>:
...

| (a) As Carl explained, the "one way" motto is fundamentally just a "cute
| saying."
|
| (b) I and others showed examples how in cases where when the underlying
| philosophy is applied, it's applied inconsistently and capriciously.
|
| (c) Nobody thus far presented a single example where there's only "one way"
| to do something or where it provides any tangible, practical benefit.

I haven't been following this "discussion" - I mean, I've read the
posts, but the leaps from topic to topic have lost me. When it comes
to development in the core language and usability, you're onto something
that I think is a genuine issue, but it doesn't help to tie it to the
"one way to do it" slogan and make that a culprit. That's ridiculous.
I think there has been some practical thinking about a healthy direction
on that issue. If your firm has a significant stake in Python's
development you ought to see if they could get with the Python business
forum, because they're reported to be putting their money where your
mouth is.

It's a cute saying, that's fine with me. Do you know where the name
Python came from? There's another popular programming language where
people maintain that the baroque variety of equivalent ways to do things
makes the language "more expressive." Python rejects that notion, it
doesn't aspire to variety for the sake of variety. Hence the slogan.

It isn't consistently applied, can't practically be. Alas, it's just
a slogan. The words don't have the magic power to strike down infidels,
so you don't really have to sweat it.

Donn Cave, do...@u.washington.edu

Fredrik Lundh

unread,
Aug 15, 2002, 1:20:19 PM8/15/02
to
skip wrote:

> Bugs fixed in the 2.3 code base are routinely backported to the 2.2
> maintenance branch.

I don't think Besemer cares much about how things work in
the real Python universe...

</F>


Robin Becker

unread,
Aug 15, 2002, 1:59:10 PM8/15/02
to
In article <npR69.1187$e5.1...@newsb.telia.net>, Fredrik Lundh
<fre...@pythonware.com> writes
I believe the real Python universe is stuck at 1.5.2 because of RH.
Nothing I have seen in 2.2 is really that much better than 1.5.2 except
perhaps for the unicode features. I would like to be able to use the 2.2
yield/generator/iterator stuff (plus perhaps a better cgitb) but it's
not back portable so reportlab stays stuck in a time warp.

Key word changes are the worst eg Andy Robinson's intricate interest
rate yield calculations will need reworking at 2.3/4 next PBF version
etc etc.

There's a lot of pain involved in moving things onwards which is why
people squeal when others demand that feature x be deprecated and
removed in 6 months.
--
Robin Becker

Carl Banks

unread,
Aug 15, 2002, 4:36:53 PM8/15/02
to
James J. Besemer wrote:
>
> Steve Holden wrote:
>
>> Well, lots of stuff is due to be deprecated, but one of the problems is the
>> screams of horror that appear in this newsgroup whenever anything is changed
>> in a potentially non-backwards-compatible way.
>
> (a) As Carl explained, the "one way" motto is fundamentally just a "cute
> saying."

Actually, my suggestion was for *you* to think of it as just a cute
saying. To those of us who are willing to look past the literal
meaning of "there should be one obvious way to do it," it is more than
just cute.

I can only tell you so many times that it's not meant to be taken
literally. It's an overstatement (among other things). In my
previous post, I tried to explain what the motto means in literal
terms. Whether you believe it or not, a lot of people understand this
true meaning, without having to be told, and without even having to
think about it.

Your objections to its literal correctness are mostly valid. But it
pointless to argue that, because it's not meant to be taken literally.

If you're not willing to look past its literal meaning yourself, I
hope you will at least acknowledge that to others, the motto is a
cute, succinct, and NON-LITERAL way to describe the Python philosophy.

James J. Besemer

unread,
Aug 15, 2002, 5:41:38 PM8/15/02
to

Skip Montanaro wrote:

> You fail to see all the times it's been applied
> successfully because those proposed features never made it into the
> language. Guido applies it routinely.

I agree Python's primary appeal is that it's fairly well designed and
consistent.

But to me this is simply good design unrelated to the slogans.
It's more akin to common sub expression elimination or normalizing
your database tables than an act of genius.

This is in stark contrast to the crock of random shit that makes
up PERL. Perl was BADLY designed by hackers who were pretty
friggin' clueless about even simple language design matters. IIRC
Wall admits he got started by hacking up C-Shell and never looked
back.

> If he didn't, I suspect we'd have a
>
> do:
> ...
> until: ...
>
> or
>
> repeat:
> ...
> while: ...
>
> construct (or some other variant),

HORRORS!

THIS is precisely an example (which I mentioned) where IMO
the slogan does not apply. Adding a standard construct like do-until
certainly would not create "bloat" where it did not already exist.
It would not be hard to implement. It would not create a burden
to understanding code. Practically everybody here already knows
what it means. For those who don't add a new section to the
language ref between sections 7.2 and 7.3. Ten or 12 lines
of text and end of issue.

It's a FAQ and a frequent question here precisely because most
programmers expect it. Y'all spend more time explaining why
it isn't there than it would cost to implement. The greater burden
for people learning the language is puzzling over the fact that it's
NOT here, not that it would be hard to learn.

Thus here's a case where IMO people echo the slogan without
really understanding the Philosophy. Rather than say, "that
sounds reasonable," they substitute the slogan for a rational
analysis. And that's just bullshit.

A switch statement is a slightly better argument for your side.
I appreciate that it would be harder because nothing from any
other language I know of carries directly over. Thus it requires
some original design and language designers should always be
extra cautious when they're being inventive. Several perfectly
adequate solutions come to mind but I concede none are significantly
better than if/elif/else. Too, switch opens several controversial
cans of worms (e.g., fall-through vs. automatic break) that maybe
never can get put back into the can. I personally put switch on
the cusp -- something certainly not so big and complicated that
it would be hard to do, mess up the language or confuse the
newbies; but also something with complications -- I can see
there may well be bigger fish to fry. But to simply dismiss
it as "more than one way" is not right.

And FWIW, I don't think I ever openly advocated switch.

And what IF these two reasonable additions had made the cut?
You talk like it would be an awful thing when it really wouldn't
be a big deal at all. There's still the thousands upon thousands
of other things that still (rightly) got left out.

> Both have been asked for many
> times. In fact, there's even a PEP for a switch statement.

I know. In my experience, FAQs often indicate a problem that
should be addressed. (And PEPs in a way are a kind of FAQ.)
Sometimes the problem can be adequately addressed by the doc
and other times they require a more fundamental change.

I think the Python community is too complacent about blithely
dismissing some of the Most FAQs when perhaps the underlying
decision should be reconsidered.

I submit if someone came out with, say, a Python++ that added
the dozen or so most often requested features, it would attract a
significant following, both from existing Python users and from
prospective newcomers. I've researched this just a little and near
as I can tell just about all of the most frequently requested items
could be added to the language in a strictly upward compatible
fashion and they could be implemented in the compiler without
changing the VM.

> I believe the
> fact that you sometimes find overlapping language constructs can be
> attributed to one of the following two reasons:

> 1. They overlap in some respects, but their natural "domains" really
> don't. This applies to your for/while/list comprehension/map
> example. BTW, you don't really need any of these iterative
> constructs. After all, we have functions and the language supports
> recursion. I say, let's get back to basics. ;-)

You guys are the ones arguing minimalist, not me. I only point to
existing redundancy as evidence the slogan doesn't really apply.

People cite the slogan as reason to deprecate and eventually remove
lambda. (Not me. I LIKE lambda.) I just say the lambda haters
should then apply same argument to list comprehensions because
they're the same domain and they're even less useful because
they're so much slower than the existing constructs. If it's healthy
for us to manually spell out do-while, why not list comprehensions?

I do not object to overlapping language constructs. I think it's perfectly
normal and A GOOD THING. It's even more to be expected in a
high level language such as Python. I think it's unavoidable. Within
reason, the costs are negligible and the benefits are significant.

But that perspective makes the inclusion of this or that PARTICULAR
feature that much more arbitrary and it makes the slogans seem all that
much more vapid.

> 2. Language design being what it is (an art rather than a science) and
> Guido's time machine notwithstanding, even the Dutch don't have a
> crystal ball to look into the future to see what the perfect language
> is.

So mistakes are inevitable. I agree. Again my present complaint is not
the redundancy, per se, but rather to the inappropriate application of the
slogans -- either to justify removing some useful existing function or to
justify keeping out some genuinely useful new one.

> Generally, Guido's gotten it right. That's why so many of us
> enjoy using Python.

I absolutely agree. Even with the benefit of hindsight, there are not
very many things I would propose to change.

However, you all are deluded to think Python is this cute, simple little
language, particularly if you take into account (as you should) all the
built-ins and important library modules. Actually Python's excellent
design and ease of learning misleads people into thinking it's a lot
smaller and simpler than it really is.

I have a collection of pocket reference cards/booklets. They all do
a decent and complete job of summarizing the languages in question.
Discounting the summary of all Linux commands, Python is by far
the longest one:

Pages Language
174 Linux Command Summary
124 Python
97 XML
89 Java Script
85 English (Strunk & White)
48 Perl 5
30 C++ (c lang, c++ lang, stdio lib)
26 Korn Shell Reference
18 Perl 4
10 Awk

The Python doc is more than twice the length of Perl5 and about 4X
the size of C++.

A similar pattern emerges from the seminal books on my bookshelf:

Pages Language
880 Lutz' Programming Python
465 Wall/Schwartz Programming Perl
398 Beazley's Python Essential Ref.
350 SQL Instant Ref.
328 Stroustrup's C++
272 K&R's C
106 Lisp 1.5

All the books cover the base language plus key library modules. All
include numerous examples. In my experience, each is sufficient
to become proficient in the language, as they were in fact the principal
books I relied on when learning and using each language (augmented
with pocket references once I got started).

You can argue that the Python books always are more complete and
somehow are proportionally longer than the language merits but even
then, we're still talking a large, sophisticated body of knowledge.
Perl may be terribly ugly and confused and C++ may include many
unnecessary complexities -- and yet they're all documented in fewer
pages than Python. Some criticisms of those other languages are
valid. However, Python is hardly small by comparison.

When we want to consider the impact of adding or removing a
particular language feature, it needs to be considered in the context
of the entire language. In practice, now in 2002 with Python 2.1+,
each of these changes are practically insignificant compared to the
entire body of knowledge.

So it's ridiculous to parrot "small is beautiful" or "one way to do it" to
argue that removing lambda() will somehow materially improve the
language or that adding the occasional do-while will precipitate chaos.

> Still, he admits to the occasional weak moment
> (lambda, for example).

Then he should really be kicking himself over list comprehensions. ;o)

I mean this strikes me as crazy. People are saying get rid of lambda
and map when they're typically faster than for or while loops and
then they praise comprehensions when they're the most unusual
and slowest of all.

In this case I'm not saying get rid of comprehensions. Just stop
talking about getting rid of lambda.

> As Steve Holden pointed out, once in the
> language, core features take a long time to get rid of. That's an
> application of "practicality beats purity". If Guido deleted every
> feature from the language as soon as he developed something better to
> replace it, I suspect he and Tim might be the only people using
> Python. It would be a very "pure" language, but not very
> "practical".

This is an important point which I mostly agree with (at length with
in a different thread).

I am not advocating deleting any features. Rather, if you read carefully,
part of my tirade is objecting to where people cite these slogans to
justify removing features.

Thanks for the thoughtful response. Even though we disagree on some
points I hope you find this discussion as interesting as I do.

Tim Peters

unread,
Aug 15, 2002, 6:51:37 PM8/15/02
to
[Carl Banks]
> ...

> I can only tell you so many times that it's not meant to be taken
> literally. It's an overstatement (among other things). In my
> previous post, I tried to explain what the motto means in literal
> terms. Whether you believe it or not, a lot of people understand this
> true meaning, without having to be told, and without even having to
> think about it.

It's times like this I'm glad I didn't channel, e.g., "all men are created
equal" from Guido <wink>.

any-idiot-can-see-that-male-fetuses-differ-ly y'rs - tim


gbr...@cix.compulink.co.uk

unread,
Aug 16, 2002, 5:12:28 AM8/16/02
to
James J. Besemer wrote:

> I mean this strikes me as crazy. People are saying get rid of lambda
> and map when they're typically faster than for or while loops and
> then they praise comprehensions when they're the most unusual
> and slowest of all.

Well, I suppose that could be because Python programmers aren't that
bothered about the speed of their language constructs. That's why they
keep on programming in Python. Another reason is that what you say isn't
true:-


Python 2.2 (#1, Dec 31 2001, 15:21:18)
[GCC 2.95.3-5 (cygwin special)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> def byComprehension(n):
... stamp = time.time()
... [x*x for x in range(n)]
... return time.time()-stamp
...
>>> def byLambda(n):
... stamp = time.time()
... map(lambda x: x*x, range(n))
... return time.time()-stamp
...
>>> def byFor(n):
... stamp = time.time()
... result = []
... for x in range(n):
... result.append(x*x)
... return time.time()-stamp
...
>>> byComprehension(10000)
0.014999985694885254
>>> byLambda(10000)
0.016000032424926758
>>> byFor(10000)
0.014999985694885254
>>> byComprehension(10000)
0.014999985694885254
>>> byComprehension(100000)
3.406000018119812
>>> byLambda(100000)
3.4839999675750732
>>> byFor(100000)
3.437000036239624
>>> byComprehension(100000)
3.406999945640564
>>> byComprehension(1000000)
59.562999963760376
>>> byLambda(1000000)
60.422000050544739
>>> byFor(1000000)
59.187999963760376
>>> byComprehension(1000000)
58.827999949455261
>>> total = 0.0
>>> for each in xrange(10000):
... total += byComprehension(100)
...
>>> total
1.7340000867843628
>>> total = 0.0
>>> for each in xrange(10000):
... total += byLambda(100)
...
>>> total
1.7500002384185791
>>> total = 0.0
>>> for each in xrange(10000):
... total += byFor(100)
...
>>> total
2.4679998159408569
>>> total = 0.0
>>> for each in xrange(10000):
... total += byComprehension(100)
...
>>> total
1.685999870300293
>>>


Graham

Michael Hudson

unread,
Aug 16, 2002, 5:13:25 AM8/16/02
to
Robin Becker <ro...@jessikat.fsnet.co.uk> writes:

> I believe the real Python universe is stuck at 1.5.2 because of RH.

Fortunately, Redhat 8 will have Python 2.2.1.

> Nothing I have seen in 2.2 is really that much better than 1.5.2 except
> perhaps for the unicode features. I would like to be able to use the 2.2
> yield/generator/iterator stuff (plus perhaps a better cgitb) but it's
> not back portable so reportlab stays stuck in a time warp.

I think the type/class/properties stuff will make quite a difference
in times to come. But obviously not if you have to cater for 1.5.2.

> Key word changes are the worst eg Andy Robinson's intricate interest
> rate yield calculations will need reworking at 2.3/4 next PBF version
> etc etc.

Surely it won't be *too* painful in this case? sed -e
's,yield,yield_,' seems to be a good start...

> There's a lot of pain involved in moving things onwards which is why
> people squeal when others demand that feature x be deprecated and
> removed in 6 months.

I really hope features aren't removed because someone thinks they're
now a bad idea, particularly if there's no alternative to the feature
in older versions. But sometimes something has to give: generators
required a new keyword, and short of making the keyword something
ridiculous that was going to break a certain amount of code.

Cheers,
M.

--
34. The string is a stark data structure and everywhere it is
passed there is much duplication of process. It is a perfect
vehicle for hiding information.
-- Alan Perlis, http://www.cs.yale.edu/homes/perlis-alan/quotes.html

RPM1

unread,
Aug 16, 2002, 7:41:43 AM8/16/02
to

"Carl Banks" wrote ...

> The real meaning of "There should be one obvious way to do it" is that
> the Python community values:

> * Sticking to common idioms
> * Avoiding the use of clever constructions
> * Avoiding coding in a way that requires a reader to "decode" it, if
> it can be avoided

Hmmm. The above three statements don't seem to have
a strong correlation to "one obvious way to do it", IMHO.
It seems more like you're talking about readablility.
Readablility *is* unquestionably a Python strong point that
Perl is lacking. Readablility may come from limited syntax
choices but I don't think that implies limited algorithmic choices.

I propose Python's motto should be:

If you can read this:
it must be Python

Just my $0.02,
Patrick

Paul Rubin

unread,
Aug 16, 2002, 12:04:53 PM8/16/02
to

Fair enough. The readable and one-and-only-obvious-way to add up the
first n values of an integer-returning function is:

sum = 0
for i in range(n):
sum += f(i)

If the function returns a string instead (remember that adding strings
means concatenation), the one-and-only-obvious-way to do it changes
only slightly:

sum = ''
for i in range(n):
sum += f(i)

Whoops! The second example works, but has quadratic running time!
So real Python programs end up full of hair like

sum = ''.join([f(i) for i in range(n)])

which seems to me to require "decoding".

I conclude from this that "one obvious way to do it" implies that Python
needs a mutable (or at least extendable) string type, that supports +=
the way list objects support appending. Maybe the above example could be:

sum = xstr('') # xstr makes an extendable string that supports +=
for i in range(n):
sum += f(n)

PEP anyone?

Donn Cave

unread,
Aug 16, 2002, 1:43:42 PM8/16/02
to
Quoth Paul Rubin <phr-n...@NOSPAMnightsong.com>:
...

| sum = ''
| for i in range(n):
| sum += f(i)
|
| Whoops! The second example works, but has quadratic running time!
| So real Python programs end up full of hair like
|
| sum = ''.join([f(i) for i in range(n)])
|
| which seems to me to require "decoding".
|
| I conclude from this that "one obvious way to do it" implies that Python
| needs a mutable (or at least extendable) string type, that supports +=
| the way list objects support appending. Maybe the above example could be:
|
| sum = xstr('') # xstr makes an extendable string that supports +=
| for i in range(n):
| sum += f(n)
|
| PEP anyone?

No, thanks! Your example was indeed enough to make one's stomach
churn with horror, but the language does not force you to use these
unreadable novelties. If it all has to fit on one line, write

sum = string.join(map(f, range(n)), '')

The conventional way to do it is

sums = []
for i in range(n):
sums.append(f(i))
sum = string.join(sums, '')

If you need an extensible string buffer, there's OOP:

sumf = StringIO()
for i in range(n):
sumf.write(f(i))
sum = sumf.getvalue()

The fact that these all work in 1.5.2 the same as they do in 2.2
is not a mark against them.

Donn Cave, do...@u.washington.edu

Christopher A. Craig

unread,
Aug 16, 2002, 3:56:36 PM8/16/02
to
"James J. Besemer" <j...@cascade-sys.com> writes:

> > Still, he admits to the occasional weak moment
> > (lambda, for example).
>
> Then he should really be kicking himself over list comprehensions. ;o)
>

> I mean this strikes me as crazy. People are saying get rid of lambda
> and map when they're typically faster than for or while loops and
> then they praise comprehensions when they're the most unusual
> and slowest of all.
>

Have you ever actually done timing tests? Lets take something simple
like the example from Guido's optimization paper:

def natural(list):
output = []
append = output.append
for item in list:
append(chr(item))
return "".join(output)

def lambda_(list):
return "".join(map(lambda item: chr(item), list))

def listcomp(list):
return "".join([ chr(item) for item in list ])


Given 100k random elements natural did this in .49 seconds, lambda in
.58, and listcomps in .48, making listcomps the fastest and lambda the
slowest. I've done timing tests on lots of loops like this and it's
generally (ordered from fastest to slowest)

map/filter/reduce on a builtin or C function
listcomps
normal for/while loop
map/filter/reduce on a lambda function

Before you argue "But you didn't need a lambda there," I know I
didn't. Mapping on the builtin chr() would have been a lot faster
than listcomps, but your argument was for keeping lambda, not map.
The function call overhead of lambda is almost always worse (maybe
always, I've never seen it better) than a listcomp. Plus there are
all sorts of language problems with lambda (They can't contain
multiple statements, they didn't used to be able to use variables from
the containing scope...)


--
Christopher A. Craig <list-...@ccraig.org>

..the Court's opinion will accomplish the seemingly impossible feat of leaving
this area of the law more confused than it found it. -- Justice Rehnquist

Anthony Baxter

unread,
Aug 17, 2002, 3:03:02 AM8/17/02
to

>>> "James J. Besemer" wrote

> How about the case where a non-upwards-compatible,
> non-bug-fix release N is followed by a release N+1 that
> fixes a bug which happened to be present in release N-1?

Do you have a point here? Can you demonstrate that this has
happened and that's it's caused you problems? Or is this just
pointless bellyaching? Python maintenance releases are _extremely_
carefully done, and the backporting exercise is kept up pretty
solidly. Right now, there are bugs in 2.1.x that have been
fixed in 2.2.x or CVS. Are they serious? No. Serious bugs would
lead to a new 2.1.x release.

If you want to put your hand up and backport every bug fix to
2.1.x, 2.0.x, or even 1.5, great! Please do so. If not, then I
don't see what you're trying to achieve here.

Anthony

--
Anthony Baxter <ant...@interlink.com.au>
It's never too late to have a happy childhood.


James J. Besemer

unread,
Aug 17, 2002, 3:02:55 AM8/17/02
to

gbr...@cix.compulink.co.uk wrote:

> James J. Besemer wrote:
>
> > I mean this strikes me as crazy. People are saying get rid of lambda
> > and map when they're typically faster than for or while loops and
> > then they praise comprehensions when they're the most unusual
> > and slowest of all.
>

> Another reason is that what you say isn't true:-

I wouldn't have been able to make this claim if I didn't have
data to back it up.

I published some benchmarks here back in April:

http://mail.python.org/pipermail/python-list/2002-April/101230.html

I would guess that comprehensions fared better in your tests
because you used the most trivial case, while my benchmark
included an "if" clause (which is more representative IMHO).

Also, you measured wall clock time (which is inherently
unreliable) while I compared CPU times.

Ha!

When I run your benchmark on my machine (with clock()
substituted for time()), for 100K iterations comprehensions
again are slowest and lambda the fastest:

comprehensions 6.1262475223
for loop 5.81651351121
map/lambda 5.65582492231

Of course, benchmarks are hard to design to produce
meaningful and fair data and relatively easy to fudge.
Assuming the clock() vs. time() substitution isn't too
gross an error, then you evidently have a machine
about twice as fast as mine, so that too may affect
benchmark results.

Therefore, I will concede that (per my earlier data)
comprehensions and loops are about the same. It's
map/lambda that can be remarkably faster.

I'll further concede that differences in runtime performance
(on this small scale) are irrelevant to much of what Pythonites do.

I still think it's the height of hypocrisy to say list
comprehensions don't bloat the language but do-while would.

Also I think it would be silly to remove map/lambda.

James J. Besemer

unread,
Aug 17, 2002, 3:35:48 AM8/17/02
to

"Christopher A. Craig" wrote:

> Have you ever actually done timing tests?

Yes, as elaborated in my reply to gbreed, or I wouldn't
have made the claim in the first place.

I noticed another difference between my benchmarks
and gbreed's and possibly yours: he definitely and possibly
you include generating the list data in the run time while I
generate the list data before measuring the effect of the
construct in question.

FWIW, when I run YOUR tests on my machine (with data
generation factored out), I get different results:

lambda_: 0.471095769706
listcomp: 0.538330365556
natural: 0.543659546563

Lambda again comes out first, though list comp beats
for loop by a nose for second place.

Skip Montanaro

unread,
Aug 17, 2002, 12:31:01 PM8/17/02
to

Paul> sum = ''
Paul> for i in range(n):
Paul> sum += f(i)

Paul> Whoops! The second example works, but has quadratic running time!
Paul> So real Python programs end up full of hair like

Paul> sum = ''.join([f(i) for i in range(n)])

Paul> which seems to me to require "decoding".

Paul> I conclude from this that "one obvious way to do it" implies that
Paul> Python needs a mutable (or at least extendable) string type, that
Paul> supports += the way list objects support appending.

There's always the UserString.MutableString class. Not sure what
performance implications it has.

0 new messages