How do I use BiPredicate and BiAssessor to test two values?
← Generics · Ref: Q712
BiPredicate and BiAssessor are the Boolean-returning two-parameter function types. They test a condition involving values 't' and 'u'.
BIPREDICATE IS PURE
BiPredicate of (T, U) takes parameters 't' and 'u' and returns 'r' as Boolean. Being pure, the test is stateless:
check <- () is BiPredicate of (String, Integer) as pure function r: length t > u
BIASSESSOR IS IMPURE
BiAssessor of (T, U) has the same signature but is NOT pure:
logCheck <- () is BiAssessor of (String, Integer) as function stdout <- Stdout() stdout.println(`Assessing: ${t} vs ${u}`) r: length t > u
USE CASES
BiPredicate: Pure comparison, matching, or relationship testing.
BiAssessor: Testing with logging, metrics, or state-dependent checks.
See Q54 for pure vs impure concepts. See Q709 for single-parameter Predicate/Assessor.
Example
defines module qa.genericsdeep.bipredicatebiassessor defines function <?- Helper that applies a pure BiPredicate. -?> testPair() as pure -> text as String threshold as Integer check as BiPredicate of (String, Integer) <- result as Boolean: check(text, threshold) <?- Helper that applies an impure BiAssessor. -?> assessPair() -> text as String threshold as Integer check as BiAssessor of (String, Integer) <- result as Boolean: check(text, threshold) defines program BiPredicateBiAssessorDemo() stdout <- Stdout() //BiPredicate: pure, stateless test of two values //Body uses 't' and 'u' for inputs, 'r' for return lengthCheck <- () is BiPredicate of (String, Integer) as pure function r: length t > u stdout.println(`'Hello' longer than 3: ${testPair("Hello", 3, lengthCheck)}`) stdout.println(`'Hi' longer than 3: ${testPair("Hi", 3, lengthCheck)}`) //BiAssessor: impure, can log during assessment logCheck <- () is BiAssessor of (String, Integer) as function stdout <- Stdout() stdout.println(`Assessing: length of '${t}' vs ${u}`) r: length t > u result <- assessPair("Testing", 3, logCheck) stdout.println(`BiAssessor result: ${result}`)
Common mistakes
E05150 — BiPredicate is pure — dynamic functions extending BiPredicate must use 'as pure function', not just 'as function'. The compiler requires the purity of the implementation to match its pure super type. See ek9 -h E05150 for details.
Incorrect:
() is BiPredicate of (String, Integer) as function
Correct:
() is BiPredicate of (String, Integer) as pure function
Other ways to ask this
- What is the difference between BiPredicate and BiAssessor?
- How do I create a BiPredicate of (String, String)?
- When should I use BiAssessor instead of BiPredicate?
Coming from another language?
Java: java.util.function.BiPredicate<T,U> — no purity distinction, supports and/or/negate. Kotlin: (T, U) -> Boolean — no pure/impure variants. Rust: Fn(&T, &U) -> bool vs FnMut(&T, &U) -> bool — structural. Go: func(T, U) bool — no purity. C#: Func<T1, T2, bool> — no purity concept. EK9: BiPredicate (pure) vs BiAssessor (impure) — compile-time enforced.
Keywords: biassessor, pure, bipredicate, function-type, comparison, test, side-effect, boolean, generic, impure, two-parameter