LISP - some function
Lisp - The some Sequence Predicate
Section titled “Lisp - The some Sequence Predicate”The some function is a powerful sequence predicate used to determine if at least one element in one or more sequences satisfies a given condition. It’s highly efficient because it stops processing and returns as soon as it finds a match.
Syntax
Section titled “Syntax”(some predicate sequence &rest more-sequences)Arguments
Section titled “Arguments”predicate: A function that accepts as many arguments as there are sequences provided. It should return a non-nilvalue for a match, andnilotherwise.sequence: The first sequence (list, vector, or string) to iterate over.
Return Value - A Key Feature
Section titled “Return Value - A Key Feature”This is very important: some does not just return T (true). It returns the first non-nil value returned by the predicate. If the predicate never returns a non-nil value after checking all elements, some returns nil (false).
Example 1: Basic Existence Check
Section titled “Example 1: Basic Existence Check”Let’s check if a list contains any even numbers.
(let ((list1 '(1 3 5 8 9)) (list2 '(1 3 5 7 9)))
;; The predicate `evenp` returns T for 8. `some` stops and returns T. (print (some #'evenp list1)) ;=> T
;; No element satisfies `evenp`, so `some` returns NIL. (print (some #'evenp list2)) ;=> NIL)Expected Output
Section titled “Expected Output”TNILExample 2: Leveraging the Return Value
Section titled “Example 2: Leveraging the Return Value”Here, we’ll check a string for the first vowel. The predicate uses member, which returns the sublist starting at the found element—a non-nil value.
(defun find-first-vowel (s) (some #'(lambda (char) (member char '(#\a #\e #\i #\o #\u))) s))
(let ((result1 (find-first-vowel "rhythm")) (result2 (find-first-vowel "lisp-is-fun")))
;; No vowels, so the predicate always returns NIL. (format t "Vowel found in 'rhythm': ~a~%" result1) ;=> NIL
;; The first vowel is 'i'. `member` returns `(#\i #\o #\u)`. ;; `some` stops and returns this list. (format t "Vowel found in 'lisp-is-fun': ~a~%" result2) ;=> (#\I #\O #\U))Expected Output
Section titled “Expected Output”Vowel found in 'rhythm': NILVowel found in 'lisp-is-fun': (#\I #\O #\U)Example 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 runs out.
;; Check if any element in list1 is greater than the corresponding element in list2(let ((list-a '(1 5 3)) (list-b '(2 4 6)))
;; 1>2 is nil. 5>4 is T. `some` stops and returns T. (print (some #'> list-a list-b)) ;=> T)
(let ((list-c '(1 2 3)) (list-d '(4 5 6)))
;; All comparisons return nil, so the final result is NIL. (print (some #'> list-c list-d)) ;=> NIL)Expected Output
Section titled “Expected Output”TNILPractical Applications
Section titled “Practical Applications”some is perfect for expressing “exists” or “at least one” conditions concisely:
- Validation: Check if any submitted data field contains invalid characters.
(some #'invalid-char-p user-input) - Searching: Quickly determine if a list of products contains any items that are on sale.
(some #'on-sale-p products) - State Checking: In a game, check if any enemy in a list is within attack range.
(some #'in-range-p enemies)
Related Predicates: every, notany, notevery
Section titled “Related Predicates: every, notany, notevery”some is part of a family of sequence predicates:
some: Is there at least one true result?every: Are all results true?notany: Are there no true results? (Is every result false?)notevery: Is there at least one false result?