Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Enumerable.All return true for an empty sequence? [duplicate]

It's certainly not a bug. It's behaving exactly as documented:

true if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty; otherwise, false.

Now you can argue about whether or not it should work that way (it seems fine to me; every element of the sequence conforms to the predicate) but the very first thing to check before you ask whether something is a bug, is the documentation. (It's the first thing to check as soon as a method behaves in a way other than what you expected.)


All requires the predicate to be true for all elements of the sequence. This is explicitly stated in the documentation. It's also the only thing that makes sense if you think of All as being like a logical "and" between the predicate's results for each element. The true you're getting out for the empty sequence is the identity element of the "and" operation. Likewise, the false you get from Any for the empty sequence is the identity for logical "or".

If you think of All as "there are no elements in the sequence that are not", this might make more sense.


It is true, as nothing (no condition) makes it false.

The docs probably explain it. (Jon Skeet also mentioned something a few years back)

Same goes for Any (the opposite of All) returning false for empty sets.

Edit:

You can imagine All to be implemented semantically the same as:

foreach (var e in elems)
{
  if (!cond(e))
    return false;
}
return true; // no escape from loop

Most answers here seem to go along the lines of "because that's how is defined". But there is also a logical reason why is defined this way.

When defining a function, you want your function to be as general as possible, such that it can be applied to the largest possible number of cases. Say, for instance, that I want to define the Sum function, which returns the sum of all the numbers in a list. What should it return when the list is empty? If you'd return an arbitrary number x, you'd define the function as the:

  1. Function that returns the sum of all numbers in the given list, or x if the list is empty.

But if x is zero, you can also define it as the

  1. Function that returns x plus the given numbers.

Note that definition 2 implies definition 1, but 1 does not imply 2 when x is not zero, which by itself is enough reason to pick 2 over 1. But also note 2 is more elegant and, in its own right, more general than 1. Is like placing a spotlight farther away so that it lightens a larger area. A lot larger actually. I'm not a mathematician myself but I'm sure they'll find a ton of connections between definition 2 and other mathematical concepts, but not so many related to definition 1 when x is not zero.

In general, you can, and most likely want to return the identity element (the one that leaves the other operand unchanged) whenever you have a function that applies a binary operator over a set of elements and the set is empty. This is the same reason a Product function will return 1 when the list is empty (note that you could just replace "x plus" with "one times" in definition 2). And is the same reason All (which can be thought of as the repeated application of the logical AND operator) will return true when the list is empty (p && true is equivalent to p), and the same reason Any (the OR operator) will return false.


The method cycles through all elements until it finds one that does not satisfy the condition, or finds none that fail. If none fail, true is returned.

So, if there are no elements, true is returned (since there were none that failed)