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