Sorting By Functions in Scheme

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 Scheme.

(import (scheme base)
        (scheme list)
        (scheme write))

(define fruits '("peach" "banana" "kiwi"))

; We implement a comparison function for string lengths.
(define (len-cmp a b)
  (- (string-length a) (string-length b)))

; Now we can sort fruits by name length using our custom comparison function.
(define sorted-fruits (sort fruits len-cmp))
(display sorted-fruits)
(newline)

; We can use the same technique to sort a list of values that aren't built-in types.
(define-record-type <person>
  (make-person name age)
  person?
  (name person-name)
  (age person-age))

(define people
  (list (make-person "Jax" 37)
        (make-person "TJ" 25)
        (make-person "Alex" 72)))

; Sort people by age using a custom comparison function.
(define (age-cmp a b)
  (- (person-age a) (person-age b)))

(define sorted-people (sort people age-cmp))

; Display the sorted list of people
(for-each
 (lambda (person)
   (display (string-append
             (person-name person) " "
             (number->string (person-age person))))
   (newline))
 sorted-people)

To run the program, save it to a file (e.g., sorting-by-functions.scm) and use your Scheme interpreter. For example, if you’re using Chez Scheme:

$ chez --script sorting-by-functions.scm
(kiwi peach banana)
TJ 25
Jax 37
Alex 72

In this Scheme version:

  1. We define a list of fruits and a custom comparison function len-cmp to compare string lengths.

  2. We use the sort function (which is part of the R7RS Scheme standard) with our custom comparison function to sort the fruits by length.

  3. We define a <person> record type to represent people with names and ages.

  4. We create a list of <person> records and define another custom comparison function age-cmp to compare ages.

  5. We sort the list of people using sort with our age-cmp function.

  6. Finally, we display the sorted results.

Note that the exact implementation might vary slightly depending on your Scheme implementation, as some functions (like sort) are not part of the minimal R5RS standard and their availability or exact usage might differ.