280: Existential Checks with any() and all()
Functional Programming
Tutorial
The Problem
Testing whether at least one element satisfies a condition (existential quantification: ∃) or whether all elements satisfy a condition (universal quantification: ∀) are the two most fundamental logical queries on collections. These appear constantly in validation: "does any user have admin rights?", "are all inputs valid?", "does any file exist?". Rust's any() and all() short-circuit — stopping as soon as the answer is determined — making them efficient even on very large collections.
🎯 Learning Outcomes
any(pred) as ∃ (existential) and all(pred) as ∀ (universal) quantificationany() stops at first true, all() stops at first falseall() returns true and any() returns false for empty iteratorsfilter() to test subsets: "all evens satisfy X"Code Example
#![allow(clippy::all)]
//! 280. Existential checks: any() and all()
//!
//! `any(pred)` is ∃, `all(pred)` is ∀ — both short-circuit.
#[cfg(test)]
mod tests {
#[test]
fn test_any_true() {
assert!([1i32, 2, 3].iter().any(|&x| x == 2));
}
#[test]
fn test_any_false() {
assert!(![1i32, 2, 3].iter().any(|&x| x == 9));
}
#[test]
fn test_all_true() {
assert!([2i32, 4, 6].iter().all(|&x| x % 2 == 0));
}
#[test]
fn test_all_false() {
assert!(![1i32, 2, 3].iter().all(|&x| x % 2 == 0));
}
#[test]
fn test_vacuous_truth() {
let empty: Vec<i32> = vec![];
assert!(empty.iter().all(|_| false)); // vacuously true
assert!(!empty.iter().any(|_| true)); // no elements
}
}Key Differences
any/all; OCaml uses exists/for_all — same semantics, different names.!any(p) == all(!p) and !all(p) == any(!p).FnMut allows side effects in the predicate (e.g., counting calls), while OCaml closures capture refs.OCaml Approach
OCaml provides List.exists (equivalent to any) and List.for_all (equivalent to all), both short-circuiting:
let has_even = List.exists (fun x -> x mod 2 = 0) [1;3;4;5] (* true *)
let all_pos = List.for_all (fun x -> x > 0) [1;2;3] (* true *)
The naming differs: exists vs any, for_all vs all — but the semantics are identical.
Full Source
#![allow(clippy::all)]
//! 280. Existential checks: any() and all()
//!
//! `any(pred)` is ∃, `all(pred)` is ∀ — both short-circuit.
#[cfg(test)]
mod tests {
#[test]
fn test_any_true() {
assert!([1i32, 2, 3].iter().any(|&x| x == 2));
}
#[test]
fn test_any_false() {
assert!(![1i32, 2, 3].iter().any(|&x| x == 9));
}
#[test]
fn test_all_true() {
assert!([2i32, 4, 6].iter().all(|&x| x % 2 == 0));
}
#[test]
fn test_all_false() {
assert!(![1i32, 2, 3].iter().all(|&x| x % 2 == 0));
}
#[test]
fn test_vacuous_truth() {
let empty: Vec<i32> = vec![];
assert!(empty.iter().all(|_| false)); // vacuously true
assert!(!empty.iter().any(|_| true)); // no elements
}
}
✓ Tests
Rust test suite
#[cfg(test)]
mod tests {
#[test]
fn test_any_true() {
assert!([1i32, 2, 3].iter().any(|&x| x == 2));
}
#[test]
fn test_any_false() {
assert!(![1i32, 2, 3].iter().any(|&x| x == 9));
}
#[test]
fn test_all_true() {
assert!([2i32, 4, 6].iter().all(|&x| x % 2 == 0));
}
#[test]
fn test_all_false() {
assert!(![1i32, 2, 3].iter().all(|&x| x % 2 == 0));
}
#[test]
fn test_vacuous_truth() {
let empty: Vec<i32> = vec![];
assert!(empty.iter().all(|_| false)); // vacuously true
assert!(!empty.iter().any(|_| true)); // no elements
}
}
Exercises
all() to validate that all elements in a Vec<String> are non-empty and contain only ASCII characters.none(pred) function using any() and negation, then verify it satisfies none(p) == !any(p).any() to short-circuit an expensive check: given a list of file paths, return true if any file has size > 1MB (simulate with len()).