Python-list digest, Vol 1 #10572 - 14 msgs

James J. Besemer jb at cascade-sys.com
Sat Apr 20 01:58:15 EDT 2002


> From: grante at visi.com (Grant Edwards)
>
> When somebody asks about a ternary operator they usually don't
> really care about a ternary operator.  What they _really_ want
> to do is to know how to solve in Python a problem that was
> sovled in C by using a ternary operator.

I couldn't disagree more.  Worse -- when you suggest rather "there's another way to do it," I'm reminded of Perl and have to stifle a gag reflex.

In decades of Software Engineering I've found inline if/then/else to be every bit as useful for expression evaluation as the if/then/else statements are for control flow.  If the capability is available in the language, it's often the clearest and most efficient way of expressing the desired behavior.  Think: binary choice.  What could
be more natural?

Dictionaries, arrays and case/switch statements are great for N-way decision making but to use them for binary choice seems a perversion.  Two-way expression branching actually is as or much more common than N-way and arguably deserves special recognition.

Python claims a Lisp heritage, which I imagine is why and/or work the way they do.   But for decision making, original Lisp most often used COND, which was an N-Way evaluation (and the only conditional construct in the language):

    (COND (( condition1 value1 ) ( condition2 value2 )...( true valueN )))

The condition of each successive sub list would be evaluated until one was found to be true then the corresponding value would be returned for the entire expression.  If no clause was true the system halted with a fatal runtime error.  Like most fully general things, COND actually was somewhat cumbersome to use.  Also, in original Lisp
AND and OR fully evaluated all arguments, so COND was the only way to express any kind of decision making.

The two-way choice was so common and vitally useful that Scheme (a successor to Lisp) adopted it as a standard form:

    (IF condition then_expr else_expr)

with the obvious meaning.  It's probably the most frequently used single construct in that language.  So from a linguistic heritage standpoint, it's actually rather odd that Python lacks some equivalent of Scheme's IF.

I am probably in the minority here in that I have little patience for people who are "confused" by or have difficulty with advanced language features.  If you purport to be a professional programmer then you should know the base language cold.  So I am not swayed by arguments that :? confuses people.  But I think part of the problem
with inline choice is that people who use it do not properly parenthesize and indent it to properly highlight what's going on.  I always split the test and the two alternatives on separate lines, with each of the latter two starting with the special operators.

    def abs( n ):
        return (( n > 0 )
                      ? ( n  )
                      : ( -n ))

You'd never write if/then/else without proper indentation (not even possible in Python ;o).  Same rules should apply to complex expressions.

Python's and/or semantics, although they may be employed to provide similar functionality, are more general, unrelated and in most cases an inappropriate substitute.

Thus although you can use and/or as a partial substitute, there are problems with the hack:

Most importantly (a) the and/or idiom strays from the desired abstraction and thus obscures the intent of the developer.

(b) Since and/or lacks clarity it arguably is more likely to people than inline choice.  And whereas :? confuses beginners, and/or (since it's an idiom rather than a language construct) is more likely to confuse more advanced users.

(c) Worst of all, the idiom doesn't even work in all cases, thus admitting the possibility of subtle, unintentional, seemingly intermittent errors, e.g.:

     x = ( len( s ) > 0
                     and s[0]
                     or -1 )     # FAILS!!  when s[0] == 0

To me clarity of expression is the most important quality of a well written program.  Binary conditional evaluation ala ?: is indispensable.  It's eminently reasonable for programmers to feel a "need" for such an addition to Python.

Biggest issue the syntax.  With ":" used the way it is in Python, C's :? syntax probably is not an easy fit.  One possibility might be to reverse the two symbols:

    x = ( len( s ) > 0
            : s[ 0 ]
            ? -1 )

Having ":" separate the test expression from the two alternatives seems sorta natural.

Another alternative would be to borrow from Algol68 and (IIRC) Algol60. They allowed if/then/else to be embedded within an expression.  Generalizing if:/else: to return a value also seems somewhat natural, so perhaps that could work.

    x = ( if len(s) > 0:   s[ 0 ]
                       else:    -1 )

Since it's all within an expression, indentation doesn't matter.

Just a thought....

Regards

--jb


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







More information about the Python-list mailing list