On 11/8/21 3:09 PM, Steven D'Aprano wrote:
> On Mon, Nov 08, 2021 at 01:43:03PM -0800, Ethan Furman wrote:

>> SomeFlag.nothing in SomeFlag.something  <--  ???
>
> I don't think that consistency with other containers is particularly
> relevant here. More useful is consistency with other flag objects.

You mean from other programming languages?

> What's SomeFlag? I presume it is some sort of Enum, or bitset.

Yes.

> Presumably SomeFlag.nothing is equivalent to a bitset of all zeroes.

Yes.

> You might have:
>
>      something = 0b11010
>
>      0 in something # ???
>      1 in something # False
>      2 in something # True
>      4 in something # False
>      8 in something # True
>      16 in something # True
>      32 in something # False
>
> So much is obvious. But what about `3 in something`?
>
> If that is interpreted as an *all* operation, you get:
>
>      3 in something --> all(i in something for i in (1, 2)) # False
>
> but if it is an *any* operation:
>
>      3 in something --> any(i in something for i in (1, 2)) # True

It's an `all()` operation.

> *If* that is how you interpret your containment tests, that implies a
> natural interpretation for `nothing in something`. The vacuous truth of
> all is True, and of any is False:
>
>      0 in something --> all(i in something for i in ()) # True
>      0 in something --> any(i in something for i in ()) # False
>
> Vacuous truth is not the only possible interpretation. If you have some
> other obvious and natural interpretation of `0 in something` then you
> probably wouldn't be asking here, but if you did, you could follow that
> interpretation. With a good reason to violate the vacuous truth rules,
> it would only be a *little* surprising.

To rephrase Wikipedia [1]: a vacuously true statement doesn't really say 
anything.

I prefer my truths to actually say something. ;-)

I don't know if there's a formal name, but in my mind, if you have something you don't have nothing. If you have a barrel with nothing in it (not even air, just a hard vacuum) then saying you have nothing in that barrel is a true statement; as soon as something is in that barrel, then saying you have nothing in the barrel is a false statement.

All of that is academic without a solid (and possibly irritating ;) use-case, so let's look at a different portion of the standard library -- opening files with `os.open()`:

    Help on built-in function open in module posix:

    open(path, flags, mode=511, *, dir_fd=None)
        Open a file for low level IO.  Returns a file descriptor (integer).

A possible `flags` value (and presumably the default value) is `O_RDONLY` which is `0`. I can imagine an implementation similar to (using integers):

    if flags == 0:
        stuff
    if flags & O_TRUNC == O_TRUNC:
        stuff
    if flags & O_RDRW == O_RDRW:
        stuff
    # preliminary stuff done
    return do_open_file(...)

If that were converted to use Flag, then the above would still work, but if 
written anew could become:

    flags = OpenFlag(flags)        # in case older code passes in an integer
    # ignoring O_RDONLY for now
    #
    if O_TRUNC in flags:
        stuff
    if O_RDRW in flags:
        stuff

Which is pretty straight-forward.  Circling back to O_RDONLY -- in the above 
snippet we either:

- need to remember that that particular flag has an actual value of 0 (and one 
of the big motivating
  factors behind Enum was not having to worry about the actual value) and use a 
different operator:

    if not flags:
    if flags == 0:  # only works because OpenFlag is an IntFlag for backwards 
compatibility
    if flags.value == 0  # works for both Flag and IntFlag

or

- recognize that a nothing cannot be in a something:

    # flags is O_RDONLY
    if O_RDONLY in flags:  # true
        pass

    # flags is O_RDRW
    if O_RDONLY in flags:  # false
        pass

    # flags is O_RDRW | O_TRUNC
    if O_RDONLY in flags:  # false
        pass

--
~Ethan~



[1] https://en.wikipedia.org/wiki/Vacuous_truth  -- last line of first paragraph
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/I5TNPPPZCUCGKRH34NAZIDL6EPUDVVKQ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to