LISP - every function
Lisp - The every Function
Section titled “Lisp - The every Function”The every function is a powerful higher-order function in Common Lisp used to test if a given predicate holds true for every element of one or more sequences. It’s a concise and expressive tool for data validation and property testing.
Syntax
Section titled “Syntax”(every predicate sequence &rest more-sequences)Arguments
Section titled “Arguments”- predicate: A function (or a symbol naming a function) that accepts as many arguments as there are sequences provided. It should return a non-
nilvalue for true, andnilfor false. - sequence: The first sequence (list, vector, or string) to be tested.
- more-sequences: Optional additional sequences.
Return Value
Section titled “Return Value”Returns T if the predicate is true for all elements. If the predicate returns nil for any element, every immediately stops processing and returns nil.
Example 1: Basic Predicate Checks
Section titled “Example 1: Basic Predicate Checks”Let’s test if all numbers in a sequence are even.
main.lisp
Section titled “main.lisp”;; Using a built-in predicate 'evenp' on a list(print (every #'evenp '(2 4 6 8 10))); => T
;; Using 'evenp' on a vector(print (every #'evenp #(2 4 6 8 10))); => T
;; A failing case with an odd number(print (every #'evenp '(2 4 5 6 8))); => NILOutput
Section titled “Output”TTNILExample 2: Using a Custom lambda Predicate
Section titled “Example 2: Using a Custom lambda Predicate”You can define a custom test on the fly using a lambda function.
main.lisp
Section titled “main.lisp”;; Check if all numbers are greater than 0 (positive)(let ((numbers '(1 5 12 99))) (print (every #'(lambda (x) (> x 0)) numbers))); => T
;; Check if all strings have a length of 3(let ((words '("cat" "dog" "ant"))) (print (every #'(lambda (word) (= (length word) 3)) words))); => T
;; A failing case(let ((mixed-words '("cat" "fish" "ant"))) (print (every #'(lambda (word) (= (length word) 3)) mixed-words))); => NILOutput
Section titled “Output”TTNILExample 3: Working with Multiple Sequences
Section titled “Example 3: Working with Multiple Sequences”When you provide multiple sequences, the predicate receives one element from each sequence at each step. The iteration stops when the shortest sequence is exhausted.
main.lisp
Section titled “main.lisp”;; Check if corresponding elements in two lists are equal(print (every #'= '(1 2 3) '(1 2 3))); => T
;; A failing case for equality(print (every #'= '(1 2 3) '(1 5 3))); => NIL
;; Check if each element in the first list is less than the corresponding element in the second(print (every #'< '(10 20 30) '(11 22 33))); => TOutput
Section titled “Output”TNILTPractical Applications and Best Practices
Section titled “Practical Applications and Best Practices”- Data Validation: Ensure all items in a dataset adhere to a specific format or constraint, e.g.,
(every #'valid-email-p user-emails). - State Checking: In games or simulations, check if all objects share a certain state, e.g.,
(every #'is-enemy-defeated? active-enemies). - Algorithm Preconditions: Verify that input data meets the requirements before running a complex algorithm.
- Pro Tip: The
everyfunction has siblings! Usesometo check if the predicate is true for at least one element,notanyto check if it’s false for all elements, andnoteveryto check if it’s false for at least one element. - Debugging Tip: If
everyreturnsnilunexpectedly, you can debug by wrapping your predicate in alambdathat prints the values it’s testing, like(every #'(lambda (x) (format t "Testing: ~a~%" x) (evenp x)) my-list).