(no) fast boolean evaluation ?

Discussion in 'Python' started by Stef Mientki, Aug 2, 2007.

  1. Stef Mientki

    Stef Mientki Guest

    hello,

    I discovered that boolean evaluation in Python is done "fast"
    (as soon as the condition is ok, the rest of the expression is ignored).

    Is this standard behavior or is there a compiler switch to turn it on/off ?

    thanks,
    Stef Mientki
     
    Stef Mientki, Aug 2, 2007
    #1
    1. Advertising

  2. En Thu, 02 Aug 2007 18:47:49 -0300, Stef Mientki
    <> escribió:

    > I discovered that boolean evaluation in Python is done "fast"
    > (as soon as the condition is ok, the rest of the expression is ignored).
    >
    > Is this standard behavior or is there a compiler switch to turn it
    > on/off ?


    The exact behavior is defined in the Language Reference
    <http://docs.python.org/ref/Booleans.html>

    "The expression x and y first evaluates x; if x is false, its value is
    returned; otherwise, y is evaluated and the resulting value is returned.
    The expression x or y first evaluates x; if x is true, its value is
    returned; otherwise, y is evaluated and the resulting value is returned.
    Note that neither and nor or restrict the value and type they return to
    False and True, but rather return the last evaluated argument. This is
    sometimes useful, e.g., if s is a string that should be replaced by a
    default value if it is empty, the expression s or 'foo' yields the desired
    value."

    Tutorial section 5.7 say the same thing in a colloquial way.

    --
    Gabriel Genellina
     
    Gabriel Genellina, Aug 2, 2007
    #2
    1. Advertising

  3. Stef Mientki

    Ian Clark Guest

    Stef Mientki wrote:
    > hello,
    >
    > I discovered that boolean evaluation in Python is done "fast"
    > (as soon as the condition is ok, the rest of the expression is ignored).
    >
    > Is this standard behavior or is there a compiler switch to turn it on/off ?
    >
    > thanks,
    > Stef Mientki


    It's called short circuit evaluation and as far as I know it's standard
    in most all languages. This only occurs if a conditional evaluates to
    True and the only other operators that still need to be evaluated are
    'or's or the condition evaluates to False and all the other operators
    are 'and's. The reason is those other operators will never change the
    outcome: True or'd with any number of False's will still be True and
    False and'ed to any number of Trues will still be False.

    My question would be why would you *not* want this?

    Ian
     
    Ian Clark, Aug 2, 2007
    #3
  4. Stef Mientki

    Evan Klitzke Guest

    On 8/2/07, Stef Mientki <> wrote:
    > hello,
    >
    > I discovered that boolean evaluation in Python is done "fast"
    > (as soon as the condition is ok, the rest of the expression is ignored).
    >
    > Is this standard behavior or is there a compiler switch to turn it on/off ?
    >


    This is standard behavior in every language I've ever encountered. If
    you are evaluating an and/or with side effects and you need both side
    effects to occur, you can trivially write functions implementing this
    behavior, e.g.

    def a():
    print 'foo'
    def b():
    print 'bar'
    def my_and(lh, rh):
    return a and b

    Then my_and(a(), b()) will evaluate both a and b and print both foo
    and bar even though a() is False.

    --
    Evan Klitzke <>
     
    Evan Klitzke, Aug 3, 2007
    #4
  5. Stef Mientki

    John Machin Guest

    On Aug 3, 8:55 am, Ian Clark <> wrote:
    > Stef Mientki wrote:
    > > hello,

    >
    > > I discovered that boolean evaluation in Python is done "fast"
    > > (as soon as the condition is ok, the rest of the expression is ignored).

    >
    > > Is this standard behavior or is there a compiler switch to turn it on/off ?

    >
    > > thanks,
    > > Stef Mientki

    >
    > It's called short circuit evaluation and as far as I know it's standard
    > in most all languages. This only occurs if a conditional evaluates to
    > True and the only other operators that still need to be evaluated are
    > 'or's or the condition evaluates to False and all the other operators
    > are 'and's. The reason is those other operators will never change the
    > outcome: True or'd with any number of False's will still be True and
    > False and'ed to any number of Trues will still be False.
    >
    > My question would be why would you *not* want this?
    >
    >


    Why? Perhaps under some compound condition like this:

    (you_are_confused and/or
    function_returns_bool_but_has__side_effects())
     
    John Machin, Aug 3, 2007
    #5
  6. Stef Mientki

    John Machin Guest

    On Aug 3, 9:19 am, "Evan Klitzke" <> wrote:
    > On 8/2/07, Stef Mientki <> wrote:
    >
    > > hello,

    >
    > > I discovered that boolean evaluation in Python is done "fast"
    > > (as soon as the condition is ok, the rest of the expression is ignored).

    >
    > > Is this standard behavior or is there a compiler switch to turn it on/off ?

    >
    > This is standard behavior in every language I've ever encountered. If
    > you are evaluating an and/or with side effects and you need both side
    > effects to occur, you can trivially write functions implementing this
    > behavior, e.g.
    >


    If each operand is of type bool (or, more generally,
    isinstance(operand, int) is true), you could trivially use the & and |
    operators.
     
    John Machin, Aug 3, 2007
    #6
  7. On Thursday 02 August 2007 15:19, Evan Klitzke wrote:
    >> I discovered that boolean evaluation in Python is done "fast"
    >> (as soon as the condition is ok, the rest of the expression is ignored).

    >
    > This is standard behavior in every language I've ever encountered.


    Then you've never programmed in VB (at least 6, don't know if .net still
    does this). Nested IF statements. AAAAAAAAAAAAAAAAAAAACK! Thankfully, I
    program mostly in Python these days. Haven't touched VB in years. Maybe
    you should have said:

    "This is standard behavior in every real programming language."

    There, that should start a flame war. :)

    j

    --
    Joshua Kugler
    Lead System Admin -- Senior Programmer
    http://www.eeinternet.com
    PGP Key: http://pgp.mit.edu/  ID 0xDB26D7CE
     
    Joshua J. Kugler, Aug 3, 2007
    #7
  8. On Thu, 02 Aug 2007 16:00:17 -0800, "Joshua J. Kugler"
    <> declaimed the following in comp.lang.python:

    >
    > "This is standard behavior in every real programming language."
    >
    > There, that should start a flame war. :)
    >


    Look at Ada... Which has such constructs as

    if x /= 0 and then y / x < z then
    ...
    end if


    Ada also has "or else" construct. These must be used to enforce
    evaluation of the LHS first, and skip evaluation of the RHS based upon
    the result. With just "and" or "or", the compiler is free to reorder the
    subexpressions for optimization.

    --
    Wulfraed Dennis Lee Bieber KD6MOG

    HTTP://wlfraed.home.netcom.com/
    (Bestiaria Support Staff: )
    HTTP://www.bestiaria.com/
     
    Dennis Lee Bieber, Aug 3, 2007
    #8
  9. Stef Mientki a écrit :
    > hello,
    >
    > I discovered that boolean evaluation in Python is done "fast"
    > (as soon as the condition is ok, the rest of the expression is ignored).
    >
    > Is this standard behavior or is there a compiler switch to turn it on/off ?


    As it was replied, its standard behavior and cannot be modified.

    IMHO, if you really need all your expressions to be evaluated, the clean
    (most readable) way may be:

    a = <first_expression which must be evaluated>
    b = <second_expression(x,y,z) which must be evaluated>
    if a and b :
    ...

    A+

    Laurent.
     
    Laurent Pointal, Aug 3, 2007
    #9
  10. Joshua J. Kugler a écrit :
    > On Thursday 02 August 2007 15:19, Evan Klitzke wrote:
    >>> I discovered that boolean evaluation in Python is done "fast"
    >>> (as soon as the condition is ok, the rest of the expression is ignored).

    >> This is standard behavior in every language I've ever encountered.

    >
    > Then you've never programmed in VB (at least 6, don't know if .net still
    > does this). Nested IF statements. AAAAAAAAAAAAAAAAAAAACK!


    I do remember an even brain-deadiest language that not only didn't
    short-circuit boolean operators but also didn't have an "elif" statement...
     
    Bruno Desthuilliers, Aug 3, 2007
    #10
  11. Stef Mientki

    Stef Mientki Guest

    Re: (no) fast boolean evaluation ? missing NOT

    John Machin wrote:
    > On Aug 3, 8:55 am, Ian Clark <> wrote:
    >> Stef Mientki wrote:
    >>> hello,
    >>> I discovered that boolean evaluation in Python is done "fast"
    >>> (as soon as the condition is ok, the rest of the expression is ignored).
    >>> Is this standard behavior or is there a compiler switch to turn it on/off ?
    >>> thanks,
    >>> Stef Mientki

    >> It's called short circuit evaluation and as far as I know it's standard
    >> in most all languages. This only occurs if a conditional evaluates to
    >> True and the only other operators that still need to be evaluated are
    >> 'or's or the condition evaluates to False and all the other operators
    >> are 'and's. The reason is those other operators will never change the
    >> outcome: True or'd with any number of False's will still be True and
    >> False and'ed to any number of Trues will still be False.
    >>
    >> My question would be why would you *not* want this?
    >>
    >>

    >
    > Why? Perhaps under some compound condition like this:
    >
    > (you_are_confused and/or
    > function_returns_bool_but_has__side_effects())
    >


    Thanks guys,
    Yes this is exactly what's going wrong ...

    Sorry, my question missed the essential "NOT",
    here is an example, that behaves different in Delphi,
    (so I guess Delphi is not a real language ;-)

    <Python>
    def Some_Function (const):
    print 'Ive been here', const
    return True

    A = True

    if A and Some_Function (4 ):
    print 'I knew it was True'
    else:
    print 'I''ll never print this'
    </Python>

    <Output>
    Ive been here 4
    I knew it was True
    </Output

    I was expected that the function would not be called,
    because A is True.

    And I agree with Laurent that it should be better to write a clean code,
    so it doesn't matter whether you write in Python or in Delphi.

    Gabriel: you pointed me to this page:
    The exact behavior is defined in the Language Reference <http://docs.python.org/ref/Booleans.html>

    <quote>
    or_test ::= and_test | or_test "or" and_test
    </quote

    Can you imagine, while I'm not a programmer, just a human,
    that I don't understand one bit of this line.

    So now I'm left with just one question:
    for bitwise operations I should use &, |, ^
    for boolean operations I should use and, or, xor
    but after doing some test I find strange effects:
    >>> A = 4
    >>> B = 5
    >>> A and B

    5
    >>> A & B

    4
    >>> A or B

    4
    >>> A | B

    5

    So if I use the bitwise operation on integers,
    "and" changes into (bitwise) "or" and vise versa.

    Is there some way to prevent / detect these kind of errors
    ( as I'm building a micro-controller simulator in Python,
    I need both logical and bitwise operators very frequently).

    cheers,
    Stef Mientki
     
    Stef Mientki, Aug 3, 2007
    #11
  12. Re: (no) fast boolean evaluation ? missing NOT

    Stef Mientki a écrit :
    > <Python>
    > def Some_Function (const):
    > print 'Ive been here', const
    > return True
    >
    > A = True
    >
    > if A and Some_Function (4 ):
    > print 'I knew it was True'
    > else:
    > print 'I''ll never print this'
    > </Python>
    >
    > <Output>
    > Ive been here 4
    > I knew it was True
    > </Output
    >
    > I was expected that the function would not be called,
    > because A is True.


    When using the *and* operator, the short-circuit evaluation is done if A
    is False (no need to know the other operand, the result cannot be True).
    But if A is True, the compiler must evaluate the second parameter to
    know the expression result.

    [note: for the or operator, the short circuit is done if first operand
    is True]

    A+

    Laurent.

    PS. See http://en.wikipedia.org/wiki/Truth_table or google for boolean
    logic tables.
     
    Laurent Pointal, Aug 3, 2007
    #12
  13. Re: (no) fast boolean evaluation ? missing NOT

    Stef Mientki schrieb:
    > John Machin wrote:
    >> On Aug 3, 8:55 am, Ian Clark <> wrote:
    >>> Stef Mientki wrote:
    >>>> hello,
    >>>> I discovered that boolean evaluation in Python is done "fast"
    >>>> (as soon as the condition is ok, the rest of the expression is
    >>>> ignored).
    >>>> Is this standard behavior or is there a compiler switch to turn it
    >>>> on/off ?
    >>>> thanks,
    >>>> Stef Mientki
    >>> It's called short circuit evaluation and as far as I know it's standard
    >>> in most all languages. This only occurs if a conditional evaluates to
    >>> True and the only other operators that still need to be evaluated are
    >>> 'or's or the condition evaluates to False and all the other operators
    >>> are 'and's. The reason is those other operators will never change the
    >>> outcome: True or'd with any number of False's will still be True and
    >>> False and'ed to any number of Trues will still be False.
    >>>
    >>> My question would be why would you *not* want this?
    >>>
    >>>

    >>
    >> Why? Perhaps under some compound condition like this:
    >>
    >> (you_are_confused and/or
    >> function_returns_bool_but_has__side_effects())
    >>

    >
    > Thanks guys,
    > Yes this is exactly what's going wrong ...
    >
    > Sorry, my question missed the essential "NOT",
    > here is an example, that behaves different in Delphi,
    > (so I guess Delphi is not a real language ;-)
    >
    > <Python>
    > def Some_Function (const):
    > print 'Ive been here', const
    > return True
    >
    > A = True
    >
    > if A and Some_Function (4 ):
    > print 'I knew it was True'
    > else:
    > print 'I''ll never print this'
    > </Python>
    >
    > <Output>
    > Ive been here 4
    > I knew it was True
    > </Output
    >
    > I was expected that the function would not be called,
    > because A is True.
    >
    > And I agree with Laurent that it should be better to write a clean code,
    > so it doesn't matter whether you write in Python or in Delphi.
    >
    > Gabriel: you pointed me to this page:
    > The exact behavior is defined in the Language Reference
    > <http://docs.python.org/ref/Booleans.html>
    >
    > <quote>
    > or_test ::= and_test | or_test "or" and_test
    > </quote
    >
    > Can you imagine, while I'm not a programmer, just a human,
    > that I don't understand one bit of this line.
    >
    > So now I'm left with just one question:
    > for bitwise operations I should use &, |, ^
    > for boolean operations I should use and, or, xor
    > but after doing some test I find strange effects:
    > >>> A = 4
    > >>> B = 5
    > >>> A and B

    > 5
    > >>> A & B

    > 4
    > >>> A or B

    > 4
    > >>> A | B

    > 5
    >
    > So if I use the bitwise operation on integers,
    > "and" changes into (bitwise) "or" and vise versa.


    No!!! Don't think that!

    Choose different numbers, and you will see that.

    The semantics for the and/or operators are spelled out like this
    (extra-verbose):


    def and(a, b):
    if bool(a) == True:
    if bool(b) == True
    return b # because it holds True == bool(b)
    return a # because it holds Fals == bool(a)

    def or(a, b):
    if bool(a) == True:
    return a
    return b


    This could be considered unfortunate because it relies on the implicit
    boolean nature of certain values like "", 0, 1, {} and so forth - but
    it's the way it is.

    However, this has _nothing_ to do with the bitwise operations! The work
    on the bits of integers, and because 5 and 4 are bitwise 0b101 and
    0x100, the

    5 & 4 -> 4 == 0b100

    and

    5 | 4 -> 5 == 0x101

    That's all!

    If you need non-circuiting and/or, write functions and and or:

    def and_(a, b):
    return a and b

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

    That will ensure argument evaluation.

    Diez
     
    Diez B. Roggisch, Aug 3, 2007
    #13
  14. Stef Mientki

    Stef Mientki Guest

    Re: (no) fast boolean evaluation ? missing NOT

    Laurent Pointal wrote:
    > Stef Mientki a écrit :
    >> <Python>
    >> def Some_Function (const):
    >> print 'Ive been here', const
    >> return True
    >>
    >> A = True
    >>
    >> if A and Some_Function (4 ):
    >> print 'I knew it was True'
    >> else:
    >> print 'I''ll never print this'
    >> </Python>
    >>
    >> <Output>
    >> Ive been here 4
    >> I knew it was True
    >> </Output
    >>
    >> I was expected that the function would not be called,
    >> because A is True.

    >
    > When using the *and* operator, the short-circuit evaluation is done if A
    > is False (no need to know the other operand, the result cannot be True).
    > But if A is True, the compiler must evaluate the second parameter to
    > know the expression result.

    Sorry you're completely right,
    and indeed I must have something very stupid !!

    thanks very much
    Stef Mientki
     
    Stef Mientki, Aug 3, 2007
    #14
  15. Re: (no) fast boolean evaluation ? missing NOT

    Stef Mientki a écrit :
    (snip)
    > Gabriel: you pointed me to this page:
    > The exact behavior is defined in the Language Reference
    > <http://docs.python.org/ref/Booleans.html>
    >
    > <quote>
    > or_test ::= and_test | or_test "or" and_test
    > </quote
    >
    > Can you imagine, while I'm not a programmer, just a human,
    > that I don't understand one bit of this line.


    This is a variant[2] of the BNF notation[1] for languages grammar.
    You'll find such notation in almost any programming language.

    [1] http://en.wikipedia.org/wiki/Backus-Naur_form
    [2] http://docs.python.org/ref/notation.html

    > So now I'm left with just one question:
    > for bitwise operations I should use &, |, ^


    yes.

    > for boolean operations I should use and, or, xor


    yes.

    > but after doing some test I find strange effects:
    > >>> A = 4
    > >>> B = 5
    > >>> A and B

    > 5
    > >>> A & B

    > 4
    > >>> A or B

    > 4
    > >>> A | B

    > 5



    Nothing strange here. You now know how boolean operators works. Bitwise
    operators are something different (while still related). Represent
    yourself ints as bit fields, ie (restricting ourselves to 4-bits words
    for the example):

    0 => 0000
    1 => 0001
    2 => 0010
    3 => 0011
    4 => 0100
    5 => 0101
    6 => 0110
    7 => 0111
    8 => 1000

    (etc)

    The bitwise operators works this way:

    1/ the & operator compares each bit of it's operands, and for each
    returns '1' if both bits are '1', else '0'. So you have:

    A & B => 4 & 5 => 0100 & 0101 => 0100 => 4

    0100
    & 0101
    ----
    0100

    2/ the | operator compares each bit of it's operands, and for each
    returns '1' if one of the bits is '1', else '0'. So you have:

    A | B => 4 | 5 => 0100 | 0101 => 0101 => 5

    0100
    | 0101
    ----
    0101


    HTH
     
    Bruno Desthuilliers, Aug 3, 2007
    #15
  16. On Fri, 03 Aug 2007 10:20:59 +0200, Bruno Desthuilliers wrote:

    > Joshua J. Kugler a écrit :
    >> On Thursday 02 August 2007 15:19, Evan Klitzke wrote:
    >>>> I discovered that boolean evaluation in Python is done "fast"
    >>>> (as soon as the condition is ok, the rest of the expression is ignored).
    >>> This is standard behavior in every language I've ever encountered.

    >>
    >> Then you've never programmed in VB (at least 6, don't know if .net still
    >> does this). Nested IF statements. AAAAAAAAAAAAAAAAAAAACK!

    >
    > I do remember an even brain-deadiest language that not only didn't
    > short-circuit boolean operators but also didn't have an "elif" statement...



    Is it a secret?

    I'm a little perplexed at why you say a language without "elif" is a good
    sign of brain-death in a programming language. I understand that, given
    the parsing rules of Python, it is better to use elif than the equivalent:

    if condition:
    pass
    else:
    if another_condition:
    pass


    But that's specific to the syntax of the language. You could, if you
    choose, design a language where elif was unnecessary:

    if condition:
    pass
    else if another_condition:
    pass

    What advantage is there to "elif", apart from it needing three fewer
    characters to type?



    --
    Steven.
     
    Steven D'Aprano, Aug 3, 2007
    #16
  17. Stef Mientki

    Neil Cerutti Guest

    On 2007-08-03, Steven D'Aprano <> wrote:
    > But that's specific to the syntax of the language. You could,
    > if you choose, design a language where elif was unnecessary:
    >
    > if condition:
    > pass
    > else if another_condition:
    > pass
    >
    > What advantage is there to "elif", apart from it needing three
    > fewer characters to type?


    It's a great boon to the authors of auto-indenting text editors.

    --
    Neil Cerutti
     
    Neil Cerutti, Aug 3, 2007
    #17
  18. Stef Mientki

    Paul Boddie Guest

    Re: (no) fast boolean evaluation ? missing NOT

    On 3 Aug, 11:45, Stef Mientki <> wrote:
    >
    > Sorry, my question missed the essential "NOT",
    > here is an example, that behaves different in Delphi,
    > (so I guess Delphi is not a real language ;-)


    Delphi is based on Pascal, and from what I can recall from my
    university textbook, there isn't any mandatory short-circuit
    evaluation in Pascal: it's an implementation-dependent feature.
    Consequently, an expression involving boolean operators in such
    languages may well evaluate each term (potentially causing side-
    effects) before determining the final result.

    Paul
     
    Paul Boddie, Aug 3, 2007
    #18
  19. Re: (no) fast boolean evaluation ? missing NOT

    Paul Boddie schreef:
    > On 3 Aug, 11:45, Stef Mientki <> wrote:
    >> Sorry, my question missed the essential "NOT",
    >> here is an example, that behaves different in Delphi,
    >> (so I guess Delphi is not a real language ;-)

    >
    > Delphi is based on Pascal, and from what I can recall from my
    > university textbook, there isn't any mandatory short-circuit
    > evaluation in Pascal: it's an implementation-dependent feature.
    > Consequently, an expression involving boolean operators in such
    > languages may well evaluate each term (potentially causing side-
    > effects) before determining the final result.


    I even thought Pascal never uses short-circuit evaluation, and always
    evaluates all terms. I might be wrong about that though; it's been quite
    a long time since I've used Pascal.

    --
    If I have been able to see further, it was only because I stood
    on the shoulders of giants. -- Isaac Newton

    Roel Schroeven
     
    Roel Schroeven, Aug 3, 2007
    #19
  20. Steven D'Aprano a écrit :
    > On Fri, 03 Aug 2007 10:20:59 +0200, Bruno Desthuilliers wrote:
    >
    >> Joshua J. Kugler a écrit :
    >>> On Thursday 02 August 2007 15:19, Evan Klitzke wrote:
    >>>>> I discovered that boolean evaluation in Python is done "fast"
    >>>>> (as soon as the condition is ok, the rest of the expression is ignored).
    >>>> This is standard behavior in every language I've ever encountered.
    >>> Then you've never programmed in VB (at least 6, don't know if .net still
    >>> does this). Nested IF statements. AAAAAAAAAAAAAAAAAAAACK!

    >> I do remember an even brain-deadiest language that not only didn't
    >> short-circuit boolean operators but also didn't have an "elif" statement...

    >
    >
    > Is it a secret?
    >
    > I'm a little perplexed at why you say a language without "elif" is a good
    > sign of brain-death in a programming language. I understand that, given
    > the parsing rules of Python, it is better to use elif than the equivalent:
    >
    > if condition:
    > pass
    > else:
    > if another_condition:
    > pass
    >
    >
    > But that's specific to the syntax of the language. You could, if you
    > choose, design a language where elif was unnecessary:
    >
    > if condition:
    > pass
    > else if another_condition:
    > pass
    >
    > What advantage is there to "elif", apart from it needing three fewer
    > characters to type?
    >


    Sorry, I forgot to mention the language did not allow to have else & if
    in the same statement. IOW :

    if some_condition then
    do_sometehing
    else
    if some_other_condition then
    do_something_else
    else
    if yet_another_condition then
    do_yet_another_thing
    else
    if your_still_here then
    give_up('this language is definitively brain dead')
    end if
    end if
    end if
    end if
     
    Bruno Desthuilliers, Aug 3, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. webposter
    Replies:
    2
    Views:
    708
    Peter Shaggy Haywood
    Sep 14, 2004
  2. J Leonard
    Replies:
    4
    Views:
    12,881
    Mark Space
    Jan 19, 2008
  3. Simon Wigzell

    boolean expression evaluation algorithm

    Simon Wigzell, Jul 24, 2004, in forum: ASP General
    Replies:
    1
    Views:
    420
    Bullschmidt
    Jul 27, 2004
  4. jens wille

    evaluation in boolean context

    jens wille, Oct 10, 2006, in forum: Ruby
    Replies:
    6
    Views:
    112
    Robert Klemme
    Oct 11, 2006
  5. Metre Meter
    Replies:
    7
    Views:
    455
    Metre Meter
    Aug 6, 2010
Loading...

Share This Page