On Tue, Aug 24, 2021 at 3:27 PM Christopher Barker <python...@gmail.com> wrote:
>
> On Mon, Aug 23, 2021 at 6:54 AM Thomas Grainger <tagr...@gmail.com> wrote:
>>
>> here's another fun one "A False midnight": https://lwn.net/Articles/590299/ 
>> https://bugs.python.org/issue13936#msg212771
>
>
> This is a great example of the problem of the assumption of zero as 
> representing false.
>

More a problem with the assumption that midnight is zero. There's
nothing at all wrong with zero being false - if, for instance, you're
looking at a timedelta, a width of zero seconds is an empty time
interval, and that can indeed be false. (Consider: What is the overlap
between segment X and segment Y? Find the intersection between them;
if the intersection has zero width, there is no overlap and the two
time periods do not collide.)

> I’ve always been ambivalent about Python’s concept of Truthiness (“something 
> or nothing”). If I were to write my own language, I would probably require a 
> actual Boolean for, eg, an if statement.
>

That becomes very frustrating. Before you design your own language, I
strongly recommend trying out REXX, C, Python, LPC or Pike,
JavaScript, and SourcePawn, just because they have such distinctly
different type systems. (Obviously you'll have tried some of those
already, but try to complete the set.) And by "try out", I mean spend
a good amount of time coding in them. Get to know what's frustrating
about them. For instance, what does "if 0.0" mean? (Python: False. C:
False. JavaScript: False. Pike: True. REXX: Error. SourcePawn: False,
but can become True if the tag changes. SourcePawn doesn't have types,
it has tags.) Similarly, what is the truth value of an empty array (or
equivalent in each language? (Python: False. C: True. JavaScript:
True. REXX: Concept does not exist. SourcePawn: Error. Pike: True.)
Not one of these languages is fundamentally *wrong*, but they disagree
on what logical choices to make. (Yes, I'm being fairly generous
towards SourcePawn here. Truth be told, it sucks.) If you're going to
make changes from the way Python does things, be sure to have tried a
language that already works that way, and see what the consequences
are.

> The fact is that what defines falsiness is use case dependent. Numbers are 
> the best example, zero. A often be a perfectly meaningful number.
>

Of course it's a perfectly meaningful number, but you won't be saying
"if x:" to figure out whether x is a meaningful number. The question
is, what *else* does it mean? For instance, if you're asking "where in
this string does the letter w first occur?", then 0 is a perfectly
meaningful result, indicating that it's found at the very start of the
string. But that's not about whether it's a number; it's whether it's
a string index.

> Which id why Brandon suggested that testing the length of a sequence was a 
> good way to be explicit about what you mean by false in a particular context.
>

When people say "explicit is better than implicit", they usually mean
"code I like is better than code I don't like". And then they get
(somewhat rightly) lampooned by people like Steven who interpret
"explicit" to mean "using more words to mean nothing", which clearly
violates the Zen.

What ARE you being explicit about? Are you stating the concept "check
if there are any users", or are you stating the concept "take the list
of users, count how many people there are in it, and check if that
number is greater than zero"? The first one is written "if users:" and
the second "if len(users) > 0:". They are BOTH explicit, but they are
stating different things.

The point of a high level programming language is that we can express
abstract concepts. We don't have to hold the interpreter's hand and
say "to figure out how many people are in the list, take the
past-end-of-list pointer, subtract the list base pointer, and divide
by the size of a list element". We say "give me the length of the
list". And one huge advantage is that the interpreter is free to give
you that length in any way it likes (directly storing the length,
using pointer arithmetic, or even iterating over a sparse list and
counting the slots that are occupied).

Only be "more explicit" (in the sense of using lower-level constructs)
if you need to be.

> So explicitly specifying that you are looking for len(container) == 0 is more 
> clear than isempty(container) would be, even  if it did exist.
>

I'm not sure that that's any better. One is asking "how much stuff is
in the container? Zero items?" and the other is asking "is this
container empty?". They're different concepts. They will (usually)
give the same result, but conceptually they're different, and it's not
a scale of "more explicit" to "less explicit".

> With duck typing, you may well not know what type you are dealing with, but 
> you absolutely need to know how you expect  that object to behave in the 
> context of your code. So if having a zero length is meaningful in your code — 
> then only objects with a length will work, which is just fine.
>

Yes. And it should make perfect sense to write something like this:

if stuff: print("My stuff:")
for thing in stuff: print(thing)

where you omit the header if there are no elements to iterate over.
What is the type of "stuff"? Do you care? Well, it can't be a
generator, since those will always be true; but it can be any sort of
collection.

Be explicit about what you care about. Don't shackle the code with
unnecessary constraints, and don't hand-hold the interpreter
unnecessarily.

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/XMZX2ADKBMANXMP7SFX4VZHL74MWQVLY/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to