[Python-ideas] except expression
Steven D'Aprano
steve at pearwood.info
Wed Feb 19 13:46:46 CET 2014
On Wed, Feb 19, 2014 at 01:04:54AM -0800, David Mertz wrote:
> I don't know if this really amounts to a *strong* objection. To me, as
> much as I try to like it reading this thread, the colon just continues to
> feel wrong to me. Yes, of course I know the analogy with lambda, and I can
> even see a certain analogy with dict literals. However, far more
> compelling to me is making it look more like the ternary expression (which
> it is really basically a special case of.
I don't believe that it is a special case of if-expressions. The two
operators are completely unrelated (although they sometimes get used for
similar purposes). LBYL and EAFP have completely different semantics.
Think "hammer and nail" and "screwdriver and screw" -- they can get used
for the same thing, but you use them in different ways and they work
according to different principles.
I think you are being misled by the fact that both ternary operators
have three arguments, and therefore there's really only a limited number
of ways you can arrange them using infix notation, the most obvious
being to place two symbols between the three operands.
In C, we have cond ? true-value : false-value
In Algol, we have ( cond | true-statements | false-statements )
In both of those forms, the first thing evaluated -- the condition --
is listed first. The proposed except ternary operator works similarly:
expr except Exception <whatever> fallback
^^^^ evaluate this first
where <whatever> might be spelled ":" or perhaps "return" or "import"
*grin*.
But in Python, the ternary if operator has the condition listed in the
middle:
true-statement if cond else false-condition
..................^^^^ evaluate this first
This truly is an odd duck. It works, at least for English speakers, but
it is very different from most ternary operators, which evaluate the
left-most operand first, not the middle one. So if we were to make the
except operator follow the lead of if, it would look something like this:
exception except expr <whatever> default
.................^^^^ evaluate this first
which is awful. So I reject your premise that we ought to make the
except ternary operator look like the if ternary operator.
> In terms of keywords to put in place of the colon, the "least bad" in my
> mind is "return." Yes, of course, we don't actually return out of a
> function call or remove a call stack element (well, unless we wind up doing
> so in the implementation). But without fuzzing one's brain *too much* one
> can think of the except expression as kind of like a function call, and
> though of that way, 'return' makes sense.
I've already talked about why I think that's an inappropriate term. So
moving along:
> The next "least bad" in my mind is 'else' because if preserved the parallel
> with 'val if cond else fallback' most closely.
So the else in a try...except statement runs when an exception does not
occur, and the else in an except expression runs when an exception does
occur. No offense intended, but this is how we get god-awful syntax like
"for...else" :-) Great concept, lousy choice of keywords.
In a for-loop, the "else" actually isn't an else at all. Like many
people, I spent years convinced that for...else executed the "else"
block if the for-loop *didn't* run, as in "run this for-loop, else run
this block". In reality the "else" block unconditionally runs after the
for-loop. (The only way to skip the else block is to break, return or
raise, which jumps right out of the for....else statement.) It's more of
a "then" rather than an "else".
In this case, the except cause is not an "else" at all. We have:
expr1 except Something else expr2
=> evaluate an expression
did an exception get raised?
else evaluate another expression
which implies that the right-most expression should be evaluated only if
*no exception occurs*. Which would be pointless.
--
Steven
More information about the Python-ideas
mailing list