Operator Precedence/Boolean Logic
Steven D'Aprano
steve at pearwood.info
Sat Jul 16 06:16:49 EDT 2016
On Sat, 16 Jul 2016 03:48 pm, Rustom Mody wrote:
> On Thursday, June 30, 2016 at 10:52:50 PM UTC+5:30, Steven D'Aprano wrote:
>> Okay, if you think that automata cannot be empty, I'll accept that. In
>> that case, then I'll change my answer and say that __bool__ for automata
>> should simply return True. All automata should be truthy.
>>
>
> I am not sure with what tone of voice you are saying that
A standard, non-sarcastic tone of voice.
> If ... “return True” is about as good -- ie useful -- as (say)
>
> def __bool__(self):
> from random import random
> return int(2*random())
>
> then I think we agree
No, I don't agree with that. "Emptiness" or "zeroness" or "falsity" doesn't
necessarily make sense for every single kind of object. If we were
modelling (say) Employees, then I would probably model all Employees as
truthy. That's easy to do: all objects are truthy by default, so I don't
have to do a thing.
If there is some concept of an "empty/null/do-nothing" automata, then I
would consider making such null automata falsey. But I'm no sure I would
care enough to bother. For example, functions are all truthy, even
do-nothing functions.
> But then there is a well-established behavior pattern in python
> captured by the contexts that raise AttributeError/NameError/TypeError etc
> viz For things that are undefined we are told politely they are undefined
>
> IOW Why say something is useless and define it rather than just leave
> undefined something that is ill-defined.
You are forgetting that you're not necessarily encountering automata in a
context where you are expecting an automata and nothing else:
x = Turing_Machine(foo)
if x:
x.run()
else:
x.blibbet()
You may encounter one in code that is expecting arbitrary objects, without
caring whether they are floats or HTTPServers or re.MatchObjects or
automata or Employees or something else:
for obj in bunch_of_objects:
if obj:
turn_left()
else:
turn_right()
There's an argument in favour of Pascal-style "true booleans" that require
you to use True and False *only* in boolean contexts; and there's an
argument in favour of Python's truthiness where any object can duck-type in
a bool context; but what doesn't make sense is to have *some* objects be
usable as true/false, forcing you to write code like this everywhere you
have to deal with arbitrary truthy objects:
for obj in bunch_of_objects:
try:
# Okay for collections, sequences, ints, floats, None,
# FooManagers, HttpServers, Dogs, Horses, Pizzashops, etc.
flag = bool(obj)
except TypeError:
# But not okay for Automata, Employees, Cats, PrintFormatters, etc.
flag = True # default to true, say
if flag:
turn_left()
else:
turn_right()
That's just awful language design. You should have either two booleans only,
or all objects should be booleans.
> If on the other hand you are giving that “return True”as a serious useful
> definition?
Sure. An automata is an object, and by default, all objects are "something"
and hence truthy. That's the "no-brainer" answer, it requires no
justification at all. If you think the answer should be something else,
*that* is what needs justification. Why shouldn't it be truthy?
> If both you and Chris tripped up on a right definition of an “empty”
> automaton and regex respectively, I believe it demonstrates that getting
> boolishness for an arbitrary type right is at least non-trivial. [FWIW My
> belief: In general its nonsensical]
Firstly, I disagree that I tripped up on anything. You haven't given any
reason to think that Automata objects shouldn't be truthy, and even if you
do, isn't that just a matter of opinion?
But in general, deciding on whether an arbitrary object should be truthy or
falsey is not hard, and most of the time you don't have to do a thing to
get the right behaviour.
- Does the object represent a collection or sequence? If so, then the right
behaviour is to delegate to `len(obj) != 0`.
- Does the object represent a number? If so, then the right behaviour is to
delegate to `obj != 0`.
- Does the object represent (in some sense) nothing rather than something?
That is, is it a reification of "there's nothing here"? E.g. something like
None in Python, null/nil pointers, Void, or Undefined. Then it should be
falsey.
- Otherwise, it represents something rather than nothing, and unless you
have pressing reason to do otherwise, it should be truthy.
--
Steven
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list
mailing list