概要
普段 Ruby を使って開発している中で、Array#all?
を使うことがちょくちょくあるのだけど、空配列のときに true になるのがちょっと違和感があった。
とはいえ、all?
は ?
(boolean を返すもの) なので、true/false を返す必要があるが、false を返すのもなんか違和感はある。
なので、true にしている理由を調査(考察)してみた結果をまとめる。
記事執筆時の環境
- Ruby: 3.1.3
結論
自分なりの考察
他の言語でもほぼそうなっているから。(元も子もない、Ruby より新しい言語もあるし。。)
空集合(くうしゅうごう)の性質1、
Vacuous truth
の概念に従っているから。(空集合は高校数学で習ったらしい、全然覚えていない。。)
※ 興味本位で調べてみたものの、正直自分には難しかったので、途中で理解を諦めました🙇♂️
(一応) ChatGPT に聞いてみた結果
わかるような、わからないような。。
なぜ違和感を感じたか
Array#any?
では、空配列のときに false になるから。
irb(main):001:0> [].all?(&:hoge?) => true irb(main):002:0> [].any?(&:hoge?) => false
調べたこと
公式ドキュメント
https://docs.ruby-lang.org/ja/3.1/method/Array/i/all=3f.html
すべての要素が真である場合に true を返します。偽である要素があれば、ただちに false を返します。 ブロックを伴う場合は、各要素に対してブロックを評価し、すべての結果が真である場合に true を返します。ブロックが偽を返した時点で、ただちに false を返します。 要素の数が 0 である配列に対しては true を返します。
他の言語ではどうなのか
※※※
使ったことのない言語もあり、特に細かく見たわけではないため間違っている可能性はあります🙇♂️
※※※
思いつく限りの言語を調べた中では、PHP 以外は true を返すことがわかった。
言語 | 関数 | 空配列のときの結果 | 公式ドキュメント |
---|---|---|---|
C# | Array.TrueForAll |
true | Link |
Elixir | all?/2 |
true | Link |
Java | Stream.allMatch() |
true | Link |
JavaScript | Array.prototype.every() |
true | Link |
Kotlin | all() |
true | Link |
Perl | all() |
true | Link |
PHP | array_reduce |
null (initial が指定されていない場合) |
Link |
Python | all() |
true | Link |
Rust | Iterator::all() |
true | Link |
Scala | forall() |
true | Link |
Swift | allSatisfy() |
true | Link |
Elixir と Kotlin でなぜ true にするのかの説明があった
Elixir
https://hexdocs.pm/elixir/Enum.html#all?/2
In an empty enumerable there is no element for which fun returns a falsy value, so the result must be true. This is a well-defined logical argument for empty collections.
(Google 翻訳) 空の列挙可能値には fun が false 値を返す要素がないため、結果は true になる必要があります。これは、空のコレクションに対する明確に定義された論理引数です。
Kotlin
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/all.html
Note that if the array contains no elements, the function returns true because there are no elements in it that do not match the predicate. See a more detailed explanation of this logic concept in "Vacuous truth" article.
(Google 翻訳) 配列に要素が含まれていない場合、述語に一致しない要素が配列中にないため、関数は true を返すことに注意してください。この論理概念の詳細な説明は、「空虚な真実」の記事を参照してください。
調査して思ったこと
空集合とか全然覚えていなかったし、今もちゃんと理解していない。(ので色々間違ってたらすみません)
興味本位で調べたらそれなりに深いところまで理解する必要があったが、今回はそこまでの元気がなかったため、ふわっとした記事になってしまった。
そもそも空配列に対して Array#all?
の結果を気にしないといけないような実装がおかしい気もしている。