Coming back to the blog after long break.
Today, almost by accident I found how logical operators work with None
in Python. The result is surprising, because it is not commutative.
(False or None) is None (None or False) is False (True or None) is True (None or True) is True (False and None) is False (None and False) is None (True and None) is None (None and True) is None
There seems to be little logic here (pun intended), but in fact it all makes sense. For “or”, if the first operand is truthy, it is returned, and the second operand is not calculated. If the first operant is falsy, the second operand is returned. For “and”, if the first operand is falsy, it is returned, and if it is truthy, the second operand is returned. The definitions are not symmetrical, which results in non-commutative behavior with None
.
UPDATE: Javascript behaves the same way with null>
. E.g. (null && false) === null
, but (false && null) === false
.
Permalink
It is called short-circuit evaluation. And I would be surprised if some dynamic scripting languge doesn’t use it.
https://en.wikipedia.org/wiki/Short-circuit_evaluation
Permalink
You are absolutely correct about short circuit. But historically, it was invented as an optimization technique, and later reused as a tool to prevent unwanted side effects [ if (p && p->data > 10) ], so one subconciously expects “or” to still be commutative if the operands are simple constants. I think this is still true in C, C++, Java and C#. But I Just checked Javascript, and guess what? It behaves like Python 🙂
Permalink
The part where the second operand is not calculated is, as you certainly know, consistent with other mainstream languages and useful in expressions like `if x and x[0]`. The part where logical operators don’t necessarily return `bool` is more surprising, but useful in expressions like `return x or default`.
Permalink
All correct. The surprising part is that it is not commutative on primitives.
Permalink
I suppose one design improvement could be not to use keyword “or” for anything but Booleans. E.g. in C# there is no “or” in the Python sense, but it has ?? and .? which cover 99% of the use cases and don’t carry implication of any kind of symmetry.
Permalink
Very well said!
Permalink
Thank you!