[Python-ideas] except expression

David Mertz mertz at gnosis.cx
Wed Feb 19 22:02:49 CET 2014


I'll accept Steven's criticism of the 'else' keyword as being terrible
because the semantics is opposite of a try/except/else block.  But I will
push back on the similarity between an except expression and a ternary
expression (as Python does it with the condition in the middle).

I wasn't in love with the Python ternary with the condition in the middle
when it was added.  I'm still not sure I *love* it, since the C-style
ternary with the condition at the front sort of feels more natural to me...
well, it would if I knew how to spell it, which didn't seem to have a good
answer within Python.  But that is a long done deal, so we have what we
have.

However, *given* the condition-in-middle form, it promotes a different
understanding of the ternary expression than C programmers have.  In C, we
think of a condition that is pretty much equally likely to be true or
false, and then list the two "branches" after that.  In Python (even though
it's obviously formally exactly equivalent in power), we think of the
"expected" value to assign, then the condition as an "exceptional"
circumstance that makes us want something else.  When I use the Python
ternary, it is almost always similar to:

  x = normal_thing if isUnexceptional(normal_thing) else something_unusual

That really does feel a whole lot like an exception in the middle there.
 Well, actually, I guess it's the negation of an exception.  But the point
is that what come right at the start is what we *expect* to usually be
assigned, then we worry about details of what to do just-in-case.

Thought of that way, it's VERY close to:

  x = normal_thing except UnusualException return something_unusual




On Wed, Feb 19, 2014 at 4:46 AM, Steven D'Aprano <steve at pearwood.info>wrote:

> 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
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140219/605b622a/attachment.html>


More information about the Python-ideas mailing list