Some syntactic sugar proposals

Mark Wooding mdw at distorted.org.uk
Thu Nov 18 04:32:23 EST 2010


Steven D'Aprano <steve-REMOVE-THIS at cybersource.com.au> writes:

> On Wed, 17 Nov 2010 16:31:40 +0000, Mark Wooding wrote:
>
> > But I don't think that's the big problem with this proposal.  The real
> > problem is that it completely changes the evaluation rule for the
> > conditional expression.  (The evaluation rule is already pretty screwy:
> > Python is consistently left-to-right -- except here.)
>
> Not quite...
>
> >>> 1+2*3
> 7
> >>> (1+2)*3
> 9

You're wrong.  Python evaluates these left-to-right, as I said.
Parentheses override operator associativity; they don't affect
evaluation order at all.

Consider:

        def say(x):
          print 'seen %s' % x
          return x

        print say(1) + say(2) * say(3)
        print (say(1) + say(2)) * say(3)

Run this program and you get

        seen 1
        seen 2
        seen 3
        7
        seen 1
        seen 2
        seen 3
        9

So definitely left-to-right.  Translating into reverse-Polish, say with
Dijkstra's shunting-yard algorithm, is enlightening: you get

        1 2 3 * +

for the first and

        1 2 + 3 *

for the second.  This preserves evaluation order; indeed, this is a
general property of the shunting-yard algorithm.

Finally, I quote from the language reference (5.13 of the 2.5 version),
just to show that (this time, at least) I'm not trying to impose
unfamiliar terminology, and that Python is defined to behave like this
and I'm not relying on implementation-specific details.  Alas, it also
highlights a genuine inconsistency, but one which might be considered
tolerable.

: 5.13 Evaluation order
: =====================
: 
: Python evaluates expressions from left to right. Notice that while
: evaluating an assignment, the right-hand side is evaluated before the
: left-hand side.
: 
: In the following lines, expressions will be evaluated in the
: arithmetic order of their suffixes:
: 
:      expr1, expr2, expr3, expr4
:      (expr1, expr2, expr3, expr4)
:      {expr1: expr2, expr3: expr4}
:      expr1 + expr2 * (expr3 - expr4)
:      func(expr1, expr2, *expr3, **expr4)
:      expr3, expr4 = expr1, expr2

So the above example is /explicitly/ dealt with in the language
reference, if only you'd cared to look.

> Not everything needs to be a one liner. If you need this, do it the old-
> fashioned way:
>
> t = foo()
> if not pred(t): t = default_value

I already explained how to write it as a one-liner:

        t = (lambda y: y if pred(y) else default_value)(foo())

-- [mdw]



More information about the Python-list mailing list