Sorting By Functions in Lisp
(defun len-cmp (a b)
(- (length a) (length b)))
(defun main ()
(let ((fruits '("peach" "banana" "kiwi")))
;; We implement a comparison function for string lengths.
;; In Lisp, we can directly compare lengths without needing a separate cmp.Compare function.
;; Now we can use the sort function with this custom comparison function
;; to sort 'fruits' by name length.
(setq fruits (sort fruits #'len-cmp))
(format t "~A~%" fruits))
;; We can use the same technique to sort a list of values that aren't built-in types.
(defstruct person
name
age)
(let ((people (list
(make-person :name "Jax" :age 37)
(make-person :name "TJ" :age 25)
(make-person :name "Alex" :age 72))))
;; Sort 'people' by age using the sort function.
;; Note: In Lisp, we're working with the actual objects, not references,
;; so there's no need to worry about the size of the struct affecting performance.
(setq people (sort people #'(lambda (a b)
(- (person-age a) (person-age b)))))
(format t "~A~%" people)))
(main)
Sometimes we’ll want to sort a collection by something other than its natural order. For example, suppose we wanted to sort strings by their length instead of alphabetically. Here’s an example of custom sorts in Lisp.
We start by defining a comparison function len-cmp
that compares the lengths of two strings. In Lisp, we can directly subtract the lengths to get the comparison result.
In the main
function, we first demonstrate sorting a list of fruits by their length. We use the sort
function, which takes a sequence and a predicate function. Our len-cmp
function serves as this predicate.
Next, we show how to sort custom structures. We define a person
struct with name
and age
fields. We create a list of person
instances and then sort them by age. For this, we use an anonymous function (lambda) as our sorting predicate, which compares the age
fields of two person
instances.
To run the program, save it to a file (e.g., sorting-by-functions.lisp
) and use your Lisp interpreter. For example, if you’re using SBCL:
$ sbcl --script sorting-by-functions.lisp
("kiwi" "peach" "banana")
(#S(PERSON :NAME "TJ" :AGE 25) #S(PERSON :NAME "Jax" :AGE 37) #S(PERSON :NAME "Alex" :AGE 72))
This example demonstrates how Lisp’s flexible function handling allows for easy implementation of custom sorting logic, both for built-in types and user-defined structures.