single-line terinary operators considered harmful

Stephen Horne intentionally at blank.co.uk
Wed Mar 5 20:55:50 EST 2003


On Wed, 5 Mar 2003 17:22:07 +0000, "Clark C. Evans"
<cce at clarkevans.com> wrote:

>| ...but that's no reason to force it on everyone in every case.
>
>Yes, but a conditional is unlike these binary operators,
>it has, to quote Dannis Reinhardt, a 'dangling else' ambiguity.
>And rather than making an ugly "endif" construct, I'd rather
>force indentation for the conditional expression.

A dangling else ambiguity is a feature of a few *particular* choices
of conditional expression syntax - it is not a fundamental feature of
all possible syntaxes and many of the proposals simply don't have this
problem.

>
>| As it happens, I tend to think of the else problem in existing if
>| statements as a (very minor) wart. I see no problem with readability
>| in something like...
>| 
>|   if b != 0 : print "a/b = ", a/b ;; else : print "div by zero"
>|
>| (using ';;' as a hypothetical 'stronger' end-of-statement operator)
>|
>
>You don't !?   In a word, *ouch*

Really. It is perfectly readable. Not 'beautiful', but that's mainly
because I'm starting from an existing syntax that isn't designed to
work this way and because I had to invent a rather ugly hypothetical
operator to make it work.

Even so, it's not meant to be art.

The single line example standing alone rather misses the point,
though. The benefit comes when there are a sequence of similar lines -
as I've mentioned earlier, vertical alignment can emphasise patterns
between those lines. Split each of those lines over two, and perhaps
add a blank line after each else line, and the patterns start to get
less clear.

I've had trouble finding a real example - which emphasises how
exceptional and unimportant the issue is, really - but I did find the
following in a C++ program...

if (Red   < 0) { Red   = 0; } else if (Red   > 255) { Red   = 255; }
if (Green < 0) { Green = 0; } else if (Green > 255) { Green = 255; }
if (Blue  < 0) { Blue  = 0; } else if (Blue  > 255) { Blue  = 255; }

I don't think any of the more spaced out alternatives would be as
clear.

That said, it's only my distaste for the C ternary operator that
stopped me writing...

Red   = (Red   < 0) ? 0 : ((Red   > 255) ? 255 : Red  );
Green = (Green < 0) ? 0 : ((Green > 255) ? 255 : Green);
Blue  = (Blue  < 0) ? 0 : ((Blue  > 255) ? 255 : Blue );

...and it wouldn't take much more repetition before I'd write a
function to do each limiting step for me. There's no doubt that...

Limit (Red,   0, 255);
Limit (Green, 0, 255);
Limit (Blue,  0, 255);

...would be even clearer still, though for just three repeats I'd
prefer not to separate out that detail.

>| While I can do that in C++ (still keeping the braces, which I really
>| don't like to omit) I've lost that capability in Python. It's
>| certainly a very good trade overall, but I don't want to see even a
>| very minor wart replicated unnecessarily.
>
>I don't see Python's indentation as a wart; I see it as an
>essential aspect which making Python code easy to read
>and understandable without distracting indicators.

I didn't say indentation is a wart. I said that the inability to get a
whole if statement, else part included, on one line - in the
exceptional case when it is useful - is a wart. An extremely minor
wart, but IMO a wart nonetheless.

It's a matter of having alternatives available for those cases when
they are beneficial. Human judgement is superior to dogmatic rules.

IMO the most readable code results when a responsible and experienced
programmer has the freedom to apply that experience - the language
should be flexible enough to support that.

>| I suspect that even Guido might be tempted if he were rewriting
>| Python, not so much to put an else on the same line but because a lot
>| of people complain about structuring by indentation from time to time.
>| Yes - there are even people (though emphatically NOT me) who see all
>| structuring by indentation as a wart.
>
>And lucky for them there are lots of languages out there,
>such as Perl, Ruby or even Java/C#, which suit their tastes
>more closely.

I tend to agree with you, except that structuring by indentation is
far from the only feature of Python that a programmer might like. If
everyone who considered even one Python feature harmful were to
abandon Python, there'd probably be no-one left - even Guido has
regretted a few past decisions.

>   I'd rather go without a conditional expression
>than have one which uses parenthesis or god-awful "endif" 
>ickyness instead of relying upon good-ole whitespace.

Parentheses are usually recognised as a way of making expressions
*more* readable, so I don't really know why you dislike them for
conditional expressions. But it's largely irrelevant anyway. Having a
conditional expression that works on a single line does not imply
having parentheses or an 'endif'. "c then a else b", for instance,
does not need linebreaks, indentation, parentheses or an endif.

The option to use indentation to structure conditional expressions
(depending on the specific syntax chosen) would probably be a good
thing - certainly novel for Python expressions, but if any syntax
deserves an Haskell-like offside rule conditional expressions are it -
but forcing the syntax to use multiple lines is unnecessary.

-- 
steve at ninereeds dot fsnet dot co dot uk




More information about the Python-list mailing list