Lisp - List Predicates



List predicates in LISP are very useful predicate for LIST operations. Following are some of the important list predicates with examples to understand their functionalities.

Example - listp - to check if object is a list

listp predicates returns true if object is a list.

main.lisp

(write(listp '(1 2 3)))  ;  T    ,A list
(terpri)
(write(listp 'a))        ;  NIL  ,A symbol
(terpri)
(write(listp "hello"))   ;  NIL  ,A string
(terpri)
(write(listp '(a . b)))  ;  T    ,A dotted list, which is still a list
(terpri)
(write(listp nil))       ;  T    ,Empty list is also a list

Output

When you execute the code, it returns the following result −

T 
NIL
NIL
T 
T

Example - consp - to check if object is a cons cell

consp predicates returns true if object is a cons cell, a building block of non-empty list.

main.lisp

(write(consp '(1 2 3)))         ; T
(terpri)
(write(consp 'a))               ; NIL
(terpri)
(write(consp "hello"))          ; NIL
(terpri)
(write(consp '(a . b)))         ; T
(terpri)
(write(consp nil))              ; NIL   ,Empty list is not a cons cell

Output

When you execute the code, it returns the following result −

T 
NIL
NIL
T 
NIL

Example - null - to check an empty list

null predicate is a standard way to check an empty list or nil list.

main.lisp

(write(null '(1 2 3)))          ; NIL
(terpri)
(write(null 'a))                ; NIL
(terpri)
(write(null nil))               ; T
(terpri)
(write(null '()))               ; T  , equivalent to nil

Output

When you execute the code, it returns the following result −

NIL
NIL
T
T

Example - member - to check if element is member

  • member returns a sublist from first occurance of element if found which is truthy value in LISP.

  • if element is not found, it returns nil

  • :test keyword can be used to specify an equality function like eql, equal , string-equal etc. to find an element.

  • :test-not keyword can be used to element is not same as equal as list elements.

main.lisp

(write(member 'b '(a b c)))    ; (B C)  ,sublist starting with the found element
(terpri)
(write(member 'd '(a b c)))    ; NIL, not found
(terpri)
(write(member 'b '(a b b c)))  ; (B B C)  ,sublist starting with the first occurence of element
(terpri)
(write(member 'b '(a (b c) d) :test #'equal)) ; NIL as ' and '(b c) are not equal
(terpri)
(write(member '(b c) '(a (b c) d) :test #'equal)) ; ((B C) D), using equal for comparison
(terpri)
(write(member 'b '(a b c) :test #'eq))      ; (B C), uses eq for comparison
(terpri)
(write(member 'b '(a b c) :test-not #'equal)) ; (A B C) , finds an element which is not equal to 'b

Output

When you execute the code, it returns the following result −

(B C)
NIL
(B B C)
NIL
((B C) D)
(B C)
(A B C)

Example - assoc - to find an association

  • assoc returns an association as a key-value pair often represented as dotted pair.

  • if association is not found, it returns nil

  • :test keyword can be used to specify an equality function like eql, equal , string-equal etc. to find an element.

  • assoc returns entire association if found.

main.lisp

; create an association list
(setq alist '((a . 1) (b . 2) (c . 3)))

(write(assoc 'b alist))               ; (B . 2)
(terpri)
(write(assoc 'd alist))               ; NIL
(terpri)
(write(assoc 'b alist :test #'equal)) ; (B . 2) ,using equal for comparison

Output

When you execute the code, it returns the following result −

(B . 2)
NIL
(B . 2)

Example - endp - to check end of the list

  • end is a more generic way to check if we're at end of list structure.

  • end works for both proper lists and dotted lists.

main.lisp

(write(endp '(1 2 3)))               ; NIL
(terpri)
(write(endp '(a . b)))               ; NIL
(terpri)
(write(endp nil))                    ; T

Output

When you execute the code, it returns the following result −

NIL
NIL
T
Advertisements