logoalt Hacker News

gpderetta12/09/20243 repliesview on HN

The question becomes why all_of returns true for an empty list. A better example would use std::accumulate and an 'and' function argument. The original STL documentation [1] described the function argument as having to model the Monoid[2] concept and have an identity value. The identity value for the 'and' Monoid is 'true'.

[1] https://www.boost.org/sgi/stl/MonoidOperation.html

[2] note: Monoid, not Monad, and yes, category theory left its mark in C++ as well.


Replies

SilasX12/09/2024

>The question becomes why all_of returns true for an empty list.

Yes! Before it became a programming problem, I considered the implications of this decision for common speech. In that case, it will generally be expected that when someone says "all my hats are green", they have at least one hat, probably because otherwise it doesn't hit the relevance threshold to make such a statement worth saying.[1]

Based on this, with my younger, hornier mind, I would joke that, "I have gone on a date with every female cheerleader at my university." (All the cheerleaders at my university are male.)

The idea being, an equally valid convention would be to read the statement as "there exists no element violating all the predicates" i.e. no one who is both a "female cheerleader at my university" and "someone I have not gone on a date with".

And this convention, it turns out, is what C's all_of (and Python's all()) uses.

But I'd still balk at someone using that trick in common speech -- it's at least an attempt to be misleading.

[1] See the "Maxim of Relevance": https://en.wikipedia.org/w/index.php?title=Cooperative_princ...

show 1 reply
GuB-4212/09/2024

And it is also what makes the most sense if you are using all_of, usually.

For example, you may want to use all_of to check if all the preconditions are met before running a command, is there are no preconditions, then you can run the command.

Or, in a test report, a test case is successful if it and all of its sub-cases are successful, if there are no sub-cases, then that part is considered successful.

Or, you are making a task runner, you exit if all the tasks are completed, if there are no tasks, then you can exit immediately.

Saying that all of nothing is true is the most appropriate behavior, both in theory and in practice.

JadeNB12/09/2024

> The question becomes why all_of returns true for an empty list.

Because it is, if you'll forgive my Haskell-ese, the only implementation that means that `all_of $ l1 ++ l2 == (all_of l1) && (all_of l2)` for all lists `l1` and `l2`, including empty ones.

show 1 reply