Common Operations on Lists

left top right

Predicate to test for a list:
(define (list? l)
  (or (null? l)
      (and (pair? l) (list? (cdr l)))))

We'd like to know how many dimensions a point has:

(define (point.dimension pt) (length pt))

(define (length l)
  (if (null? l)
      0
      (+ 1 (length (cdr l)))))

We'd like the coordinate on a particular axis:

(define (point.coord pt dim) (list-ref pt (- dim 1)))
(define (point.x pt) (point.coord pt 1))
(define (point.y pt) (point.coord pt 2))
(define (point.z pt) (point.coord pt 3))

(define (list-ref l n)
  (cond ((null? l) (error "..."))
        ((= 0 n) (car l))
        (else (list-ref (cdr l) (- n 1)))))

We'd like to find distance from origin:

(define (point.to-origin pt)
  (sqrt (add-up (map square pt))))

(define (map fn list-of-values)
  ; Returns list of same length as list-of-values
  (if (null? list-of-values)
      '()
      (cons (fn (car list-of-values))
            (map fn (cdr list-of-values)))))
Our first attempt to write add-up:
(define (add-up list-of-numbers)
  (if (null? list-of-numbers)
      0
      (+ (car list-of-numbers)
         (add-up (cdr list-of-numbers)))))
Or we can use a common higher-order abstraction:
(define (accumulate initial-value operation list-of-elements)
  (if (null? list-of-elements)
      initial-value
      (operation (car list-of-elements)
                 (accumulate initial-value operation
                             (cdr list-of-elements)))))

(define add-up (lambda (l) (accumulate 0 + l)))
We'd like to filter out those that are more than 1 unit from the origin:
(define (inside-unit-sphere? point)
  (<= (point.to-origin point) 1))

(define (those-inside-unit-sphere list-of-points)
  (filter (lambda (pt) (<= (point.to-origin pt) 1))
          list-of-points))

(define (filter test list)
  (cond ((null? list) '())
        ((test (car list))
         (cons (car list) (filter test (cdr list))))
        (else (filter test (cdr list)))))
Now we can do things like:
(define (how-many-in-unit-sphere points)
  (accumulate 0 +
    (map (lambda (pt) 1)
         (filter inside-unit-sphere? points))))

Jim Miller W3C