For review: PEP 308 - If-then-else expression

Andrew Koenig ark at research.att.com
Sat Feb 8 09:40:38 EST 2003


James> It *might* be possible to obtain the effects of the proposed
James> expression in a more general way by extending the semantics of
James> the following existing construct:

James>    ("html", "text")[is_html(msg)]

This is the third message of this kind (by three different authors,
I think) that has the two alternatives swapped!  This fact, by itself,
convinces me that this particular form is a Bad Idea.  It would be
much better to write

        { True: "html", False: "text" }[is_html(msg)]




James> The above expression provides the string "html" or "text"
James> depending upon the return value of the function "is_html".

James> If a special case were to be recognized by the parser, that of
James> a tuple "literal" followed immediately by an index selector,
James> then only the tuple item selected by the calculation of the
James> index would need to be actually calculated (a form of "lazy
James> evaluation") as in the following example:

James>    (calc_value0(r), calc_value1(r), calc_value2(r))[index_val(x)]

James> The selector "index_val(x)" would be computed first, then,
James> depending upon the value of the index, the appropriate
James> "calc_value" (0, 1, or 2) would be the only "calc_value" to be
James> computed as the value of the expression.

You're right -- it could be.  But I don't like the idea, because it
would mean that the semantics of an expression would change based on
the surrounding context.

James> Such an approach might present difficulties in parsing, but it
James> might have the advantage of being more general (eg. extending
James> to more than two possible selections) and more intuitive.

James> There would be a risk of breaking some current code that
James> depends upon such a construction and also depends upon
James> side-effects depending upon executing all of the various
James> functions "calc_value", however, I suspect that few programmers
James> would intentionally write such code.

What's funny is that I just finished posting a message about how ML
handles this situation, which is by defining an if-statement as a special
form of a case statement.  Indeed, your second example above translates
naturally into ML as

        case index_val(x)
          in 0 => calc_value0(r)
           | 1 => calc_value1(r)
           | 2 => calc_value2(r)

Because this is an expression, not a statement (ML does distinguish between
expressions and statements, and this really is an expression), you could
also factor it this way:

        (case index_val(x)
          in 0 => calc_value0
           | 1 => calc_value1
           | 2 => calc_value2) (r)

Also, because ML does not require parentheses around function arguments,
you could even write it this way

        (case index_val x
          in 0 => calc_value0
           | 1 => calc_value1
           | 2 => calc_value2) r

You may think this looks really weird--but as I've said in another thread,
I think "weird" is often just another way of saying "unfamiliar."

-- 
Andrew Koenig, ark at research.att.com, http://www.research.att.com/info/ark




More information about the Python-list mailing list