Common Operations on Lists |
|
(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 |