(define new-bitmap (lambda [width height] (initialised-sequence height (initialised-sequence width 0)))) (define initialised-sequence (lambda [length element] (is-helper 1 length element))) (define is-helper (lambda [count end element] (if (> count end) [] (cons element (is-helper (1+ count) end element))))) (define on (lambda [x y bitmap] (= 1 (nth x (nth y bitmap))))) (define off (compose not on)) (define compose (lambda [f g] (lambda args (f (g . args))))) (define turn-on (lambda [x y bitmap] (set-bitmap 1 x y bitmap))) (define turn-off (lambda [x y bitmap] (set-bitmap 0 x y bitmap))) (define set-bitmap (lambda [state x y bitmap] (letrec [[... Idea! Make a more abstract initialised sequence! ;;; suppose we had initialised-sequence length element-function (define initialised-sequence (lambda [length element-function] (is-helper 1 length element-function))) (define is-helper (lambda [count end element-function] (if (> count end) [] (cons (element-function count) (is-helper (1+ count) end element-function))))) (do this by modification of above!) ;;; Another definition: (define initialised-sequence (letrec [[helper (lambda [count] (if (= count length) [] (cons (element-function count) (helper (1+ count)))))]] (helper 0))) ;;; Redefine NEW-BITMAP using this: (define new-bitmap (lambda [width height] (initialised-sequence height (constant (initialised-sequence width (constant 0)))))) (define CONSTANT (lambda [x] (lambda args x))) ;;; Then we can finally define: (define SET-BITMAP (lambda [state x0 y0 bitmap] (initialised-sequence (height bitmap) (lambda [y] (if (= y y0) (initialised-sequence (width bitmap) (lambda [x] (if (= x x0) state (nth x (nth y bitmap))))) (nth y bitmap)))))) (define HEIGHT length) (define WIDTH (lambda [bitmap] (length (first bitmap)))) ;;; Next define REVERSE-VIDEO ;;; There is an obvious double-recursion: from x0 to x1, and ;;; within that from y0 to y1, call SET-BITMAP. But two ;;; problems: ;;; a) need to INVERT it; not just set it on or off ;;; b) would be terribly inefficient. ;;; Plan: modify set-bitmap, make a REVISE-BITMAP ;;; ;;; (define revise-sequence (lambda [sequence revise-function] (letrec [[helper (lambda [count] (if (> count (length sequence)) [] (cons (revise-function count (nth count sequence)) (helper (1+ count)))))]] (helper 1)))) (define REVERSE-VIDEO (lambda [x0 x1 y0 y1 bitmap] (revise-sequence bitmap (lambda [y row] (if (and (>= y y0) (<= y y1)) (revise-sequence row (lambda [x element] (if (and (>= x x0) (<= x x1)) (absolute-value (- element 1)) element))) row))))) ;;; Better yet: (define BETWEEN (lambda [x lower upper] (and (>= x lower) (<= x upper)))) (define REVERSE-VIDEO (lambda [x0 x1 y0 y1 bitmap] (revise-sequence bitmap (lambda [y row] (if (between y y0 y1) (revise-sequence row (lambda [x element] (if (between x x0 x1) (absolute-value (- element 1)) element))) row))))) ;;; Earlier stuff on points: (define x-coord (lambda [point] (first point))) (define x-coord first) (define y-coord (lambda [point] (second point))) (define x-coord second) (define radius (lambda [point] (square-root (* (first point) (second point))))) better: (define radiusradius (lambda [point] (square-root (* (x-coord point) (y-coord point))))) (define theta (lambda [point] (arctan (/ (x-coord point) (y-coord point))))) (define make-point-xy (lambda [x y] [x y])) (define make-point-rt (lambda [radius theta] [(* radius (cos theta)) (* radius (sin theta))])) Similarly: (define x-coord (lambda [point] (* (radius point) (cos (theta point))))) (define y-coord (lambda [point] (* (radius point) (sin (theta point))))) (define radius first) (define theta second) (define make-point-xy (lambda [x y] (let [[radius (square-root (+ (* x x) (* y y)))]] [radius (arcsin (/ x radius))]))) (define make-point-rt (lambda [radius theta] [radius theta]))