[erlang-questions] lists:all/2 unexpected result for the empty list

Richard O'Keefe ok@REDACTED
Wed Jul 20 04:44:11 CEST 2011

```On 20/07/2011, at 10:16 AM, James Aimonetti wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Was wondering the reasoning for lists:all/2 returning true when passed
> an empty list as the second parameter?
>
> lists:all(some_fun/1, []) => 'true'

Because that's the way universal quantifiers are *SUPPOSED* to work.

lists:all(F, L) is true [assuming the types are right]
precisely when there is no element X of L such that F(X) is false.

Since [] has no elements, it cannot have any that would falsify some_fun.

It's just the same in Lisp:
(EVERY predicate list...) returns false as soon as any invocation of predicate
returns false. If the end of a sequence is reached, every returns true.
Thus, every returns true if and only if every invocation of predicate returns true.

It's just the same in Smalltalk:

aSequence allSatisfy: [:x | some test on x]
answers false if aSequence has some element falsifying the test,
true otherwise, so #() allSatisfy: anything is true.

It's just the same in Haskell.

It's also just the same in mathematics, where
(∀x∈∅) p(x)
is required to be true.

> The definition in lists.erl for all/2 shows why it returns true:

No, the definition shows HOW it returns true, but not WHY.
WHY is because all/2 is an iterated "and", and the identity
for "and" is "true".

One of the major weaknesses in the Aristotelian syllogisms was
the assumption that "all Xs are Ys" entailed there being at
least one X.  The convention used in Erlang is that of modern
logic.

In just the same way, existential quantifiers are supposed to return
false if you quantify over an empty set, sums to return 0,
products to return 1, and other such operations to return their
identities.

```