PEP 308: A PEP Writer's Experience - PRO
James J. Besemer
jb at cascade-sys.com
Fri Feb 14 10:43:16 EST 2003
Andrew Dalke wrote:
> Erik Max Francis:
>
>>Using a conditional operator as the sole expression in the conditional
>>of an if statement is pretty bad style in any language. My point about
>>it being red herring is that this is simply a general style issue in any
>>language, not just Python. I suspect that its use will be very rare in
>>Python, just like it is in C, C++, Java, or Perl.
>
>
> Sure, and most people will at the very least write it in parens, as
>
> if (x if y else z):
Certainly parens around conditional operators are to be encouraged in most
cases, if only as a purely stylistic matter. In fact, parens are required by
the syntax in what is listed as the leading proposal in the PEP.
If the selected alternative turns out to NOT require parens, then I would
lobby to have a rule added to PEP-8 requiring them. The style guide is an
excellent way to warn people away from inappropriate usage.
> And I agree that its use will be rare. I just think it will also be
> used incorrectly (when other more appropriate Python idioms
> are available) about 1/3 of the time.
This prompts me to review for the record my several objections to the bulk of
your 'analyses' thus far.
As indicated above, you object to ANY use of a conditional operator in ANY
circumstance where ANY remotely plausible alternative already exists in
Python. You have consistently classified any such use as "abuse". While I
acknowledge that this is a legitimate OPINION for you to hold (and that it's
a view shared by others), I disagree completely and I think this is way too
strict a criteria for real life. I think you grossly underestimate the
ability of even newbie programmers use the new feature without getting into
major trouble and for them. With appropriate guidance from the style guide,
I believe the actual incidence even of truly cryptic forms will be negligible
in practice.
Second, much of your past 'analysis' devote a substantial amount of time and
effort trying to find some kind, any kind of rationale for rejecting most of
the example conditional forms presented along the way. E.g., Andrew Koenig's
early on cited a small application where he finds 7 examples of cond, ALL of
which he claims (and I agree) are suitable examples for Python. This
predicts a fairly high rate of usefulness, one instance in every 400 lines.
You arbitrarily reject several of his examples, thereby unilaterally reduce
his statistic to one more consistent with your own view. I cited a dozen or
so examples from the Python source code along with my opinion that ALL of
them were examples of things that might well arise in normal Python
programming. You disagreed and argued at length that ALL of the alternatives
were "abuse" and thus there'd never be an occasion to use any of the examples
when writing Python code. This was kind of pointless, as there was no
statistical significance to the handful of samples I presented. Worse, your
reasoning in most cases was totally incredible. E.g., in one case, you
completely rewrite the code to avoid a choice. While this is certainly a
possible alternative and may well reflect your individual preference in the
matter, it nowhere demonstrates that the original was in any way
inappropriate. Another set of examples (which you admitted was excellent)
you said would not apply in Python because the C example was in a macro body.
For some unfathomable reason you argued that "in Python, the inlining would
be done by hand, which means having [the expression] be used many times
instead of simply using [the name]." You really said that! This is patently
absurd, as clearly the Python equivalent would be to define a function and
call it in the body of the code, same as the macro. There are other places
where you similarly reject various examples for no good reason, in direct
contradiction to others' views, and always with the net effect of cooking the
books consistent with your stated bias.
The hardest case for me to counter argue is C examples which amount to some
kind of a min or max function. You say, this would be "abuse" in Python
because Python has min/max functions. But C and C++ also have min and max as
part of their standard "built-ins". Arguably min/max is better in both
languages. Still, I would give benefit of the doubt to the developer that
for reasons I can't fully divine, spelling it out was preferable in this
case. Maybe it simply was more convenient at the time. I seem to recall
using if/else in Python very early on, before I had absorbed the fact that
min and max were built-ins. Far as I'm concerned, the following alternatives
are all acceptable:
if a < b:
return a
else:
return b
( a < b ? a : b )
min(a, b)
That you can figure out at a glance what's going on (once you learn the
language), IMHO makes this all a non issue. I know you (and others)
disagree, but it's still a matter of opinion, not some objective reality. So
my and others' contrary views are just as valid as yours.
Third, there are a number of places where you boldly pick numbers or ratios
purely out of the air. At one early point I seem to recall you arbitrarily
assert 1 in 4 uses of the PEP will be "abusive". (I could be wrong about
this particular; looking just now I timed out without locating this statement
in the thousands of messages this week.) But elsewhere you say alternatively
25-50% chance of abuse and then 1/1 to 1/3 odds. Above you simply say 1/3.
I know there's no hard data and the choice IS completely arbitrary but you
would at least SEEM more rigorous if you'd pick an assumption and stick with
it. In any case, most of your choices have consistently had the effect of
artificially inflating the estimated hazard or to reduce the estimated value.
So, even within the framework of your 'analyses', there is considerable room
for reasonable people to legitimately maintain radically different opinions
about the calculated likelihood of "abuse". I'll stipulate that it is non
zero but, if I were to pick numbers out of the air, I'd say it's more like 1
in 50 or 1 in 100 rather than 1 in 3. Furthermore, for the various
assumptions you make along the way, assumptions more favorable to the PEP
arguably are equally valid. Without going back and re-running all the
numbers, I submit that including most examples from C/C++ (as I and others
would do) vs. excluding most examples (as you have argued) translates to
considerably different bottom lines. Certainly changing the fudge factors
affecting suitability of C examples for Python and the intrinsic odds of
Python abuse (the real issue), would make a big difference in the conclusion,
regardless of the underlying code base. Since different sets of assumptions
lead to radically different conclusions, I'm not sure we can attach much
significance at all to any qualitative 'analyses' such as the ones that you
have presented. I question if it's even better than nothing at all. In the
end, they're all simply an elaborate statement of conviction by whomever
picks the assumptions. Liars, damned liars and analysts.
Now, I'm not accusing you of intentional dishonesty. For the most part, all
your work was done in the open and you invited others to propose counter
examples. Arguably it's partly my fault for not speaking up sooner but
frankly, I simply couldn't keep up with your volume and I was distracted by
other arguments I though were more important at the time. In most of your
analyses, some fudge factor was intrinsic to the reasoning. Since you were
doing all the work, you got to pick the initial value and I agree that is
fair as far as it goes. I don't even believe that your bias is intentional.
I bet you sincerely believe everything you did was 100% objective and
unbiased. Psychological experiments have shown that people tend to
UNCONSCIOUSLY introduce bias to pure measurement tasks if they are given a
preconception about the 'correct' outcome. It's hard to see how people with
passionate feelings can ever avoid letting their bias cloud their perception
and reasoning.
I don't even necessarily object to most of what you say, however biased they
may be. As an ARGUMENT -- as an elaborate expression of your admittedly
biased viewpoint -- it's still a valid OPINION and I respect it as far as
that goes. You're entitled to your opinion and nobody can object so far as
it's a statement of opinion. But I object to your pretending that this
analysis reflects some concrete, objective reality, removed from your own
biases. And that's the main reason I am compelled to post this rebuttal.
My biggest disagreement overall is that you classify as 'abuse' ANY use that
happens to have some other Python alternative. I think this is an extreme
and unreasonable criterion to start with. I know you like to think and say
"there's only one way to do it" but that's just a myth. It's cute anti-Perl
rhetoric but little more. Like with any mature programming language, Python
already has myriad different ways to do just about everything. Arguably some
alternatives are better than others but for most part 'arguable' is the key
word. E.g., for loops, map()/lambda(), and list comprehensions are each
mutually redundant. But different people prefer one or the other for
different circumstances. It's usually a highly subject matter, the very
opposite of your 'one way' point of view. What's best in any given case
ultimately is a matter of personal preference, as it should be.
Finally, this small construct is far from the biggest opportunity for abuse
in the wonderful world of Python. The examples are too numerous to list.
Off the top of my head, I bet some really strange lists can be created based
on the fact that list comprehensions can nest arbitrarily deep. One or more
closures may appear as part of the expression left of the 'if', one or more
may appear in the expression following any 'for...in', and one or more may
appear in the expression following any 'if...'. E.g.,
[[[2**i for i in xrange(j)]
for j in xrange(k)]
for k in xrange(9)]
is kind of cool. This is just random to see if it worked. Jeeze, you guys
let this this hippopotamus into the tent (one with TWO major preexisting
alternatives) and then you turn around and complain about trivial little
PEP308. I'm only pointing out the hypocrisy when you talk about Python as is
being so immune to abuse. It would have been a gross mistake to NOT make
closures fully regular and flexible like this. Languages get their power and
(ironically) their simplicity by being general like this and NOT including
arbitrary restrictions.
> C/C++ idioms dominate
> how many people think about programs, and so those constructs
> will come to mind often before the Python ones, even for people
> who are good Python programmers.
I think this is a true statement that undermines some of your stated concerns.
It's a fact that a large majority of programmers are trained in C and C++,
particularly in the PC/Unix world, Python's primary market. If it's given
that many, perhaps most potential newcomers will have some experience with
those languages, then it's disingenuous to argue that they'll necessarily
have huge problems with adding PEP 308. In fact, making Python a little more
attractive to C users might do more to encourage growth than any other change.
If only Guido had gone ahead and simply added ?: back in the beginning (when
he copied so many other operators from C), I expect y'all now days couldn't
live without the damn thing.
Regards
--jb
--
James J. Besemer 503-280-0838 voice
2727 NE Skidmore St. 503-280-0375 fax
Portland, Oregon 97211-6557 mailto:jb at cascade-sys.com
http://cascade-sys.com
More information about the Python-list
mailing list