[Tutor] 'or' in assignment (not if statement)?

Steven D'Aprano steve at pearwood.info
Fri Dec 10 14:25:56 CET 2010


ALAN GAULD wrote:
> 
>> Doesn't  short-circuit evaluation refer specifically to the behavior
>> where arguments  are only evaluated if they need to be? It's a very
>> useful feature, but not  technically required for the "val = val or 1"
>> behavior to work.
> 
> Its essential.
> If Python always evaluated all parts of a boolean expression 
> the return value would always be the last item.

You can simulate non-short-circuit behaviour with a function:

def or_(a, b):
     if a: return a
     return b

x = 0
or_(True, 1/x)

Unlike the short-circuiting `or` operator, this version evaluates the 
1/x even though it doesn't end up being used. This was one of the 
reasons why the ternary `if` operator had to be handled by syntax, 
rather than having people write a function:

ifte(condition, a, b):
     if condition: return a
     else: return b

ifte(len(x) > 0, x[0], "nothing there")

This will fail if x is an empty list, unlike this:

x[0] if len(x) > 0 else "nothing there"

which works because the Python interpreter knows not to evaluate x[0] 
unless needed.


  It's the fact that
> Python knows that if val is true then it doesn't need to evaluate 
> the second term that causes it to return val rather than 1.

That's what makes it short circuiting, but that's not why it returns the 
first argument. `or` in standard Pascal doesn't short-circuit. Take this 
example `or.p` file:

[steve at sylar pascal]$ cat or.p
program main(input, output);

function f1(a:integer):boolean;
   begin
     writeln('calling f1');
     f1 := True;
   end;

function f2(a:integer):boolean;
   begin
     writeln('calling f2');
     f2 := True;
   end;

var
   n: integer;
   f: boolean;

begin
   n := 0;
   f := f1(n) or f2(n);
end.

[steve at sylar pascal]$
[steve at sylar pascal]$ gpc --no-short-circuit or.p
[steve at sylar pascal]$ ./a.out
calling f1
calling f2


(gpc defaults to the sensible but non-standard short-circuit behavior, 
and you have to pass a compiler option to get the standard behaviour.)


>> Also,  returning on of its operands rather than a boolean is hardly a
>> quirk, since  basically all dynamic languages do it ever since perl
>> made "val = val or 1"  an idiom (at least, I think it was perl).
> 
> Its a quirk in that it is not the intuitively expected behaviour.
> It's a boolean expression you would reasonably expect a 
> true boolean result.

That brought a smile to my face! That's very amusing, the idea that 
*boolean algebra* is intuitively expected!

As an experiment, offer to buy your wife (or girlfriend, boyfriend, 
significant other, or if all else fails, mum) dinner, and ask if she'd 
prefer to go to an Italian or Chinese restaurant. If she says that she 
doesn't understand the question, because restaurants aren't True/False 
boolean values, then you might have a point :)



-- 
Steven



More information about the Tutor mailing list