Compound Data Structures, test and key

:test -> typically, when working with strings :key -> for Compound objects

#' is a "reader macro" to refer to functions. Aka a macro used at the step of reading the source files, not a compile-time macro, the usual one.


(find "hello" (list "foo" "hello"))
;; returns nothing
;; we need another equality function
(find "hello" (list "foo" "hello") :test #'equal)

;; sort this?
(defparameter *list-of-lists* '( (1 9) (3 7) (2 8) ))
;; copy the list before sorting it, since it's a destructive function.
(sort (copy-seq *list-of-lists*) #'< :key #'first)


;;; Sequence function with Compound objects
(defparameter *list-of-plists*
  (list (list :x 1 :y 2)
        (list :x 10 :y 20)))

;; find objects whose coordinate :x is 10
(find 10 *list-of-plists* :key (lambda (plist)
                               (getf plist :x)))

;; written with an accessor function
(defun coord-x (plist)
  (getf plist :x))

(find 10 *list-of-plists* :key #'coord-x)

(defstruct point 
  x y)
;; make-point = constructor
:: point-x = accessor
;; point-y

(defparameter *list-of-structs*
  (list (make-point :x 1 :y 2)
        (make-point :x 10 :y 20)))

(find 10 *list-of-structs* :key #'point-x)


;; Combining :key and :test

(defstruct point
  x y name)

(defparameter *list-of-compound-objects*
  (list (make-point :x 1 :y 2 :name "point 1")
        (make-point :x 10 :y 20 :name "point 2")))

(find "point 2" *list-of-compound-objects*
      :key #'point-name
      :test #'string=
      )