2
Procedures
2.1. Defining and Applying Procedures
2.1.1. The Environmental Influence
(define (square z) (* z z))
(define (dist x y) (abs (- x y)))
(define num
(- 1 (+ (square (sin 3)) (square (cos 3)))))
(define (close? a b) (<= (dist a b) _delta))
(define _delta 1e-20)
(define (small? z) (close? z 0))
2.1.2. The Modularity Principle and Top-Down Design
; = volume of length len & radius rad capped pipe
(define (pipe-volume len rad)
(+ (cylinder-volume len rad)
(sphere-volume rad)))
; = volume of length len & radius rad cylinder
(define (cylinder-volume len rad)
(* len (circle-area rad)))
(define four-thirds-pi (* (/ 4 3) pi))
(define pi (acos -1)) ; since (cos pi) = -1
; = volume of radius rad sphere
(define (sphere-volume rad)
(* four-thirds-pi (cube rad)))
; = area of radius rad circle
(define (circle-area rad)
(* pi (square rad)))
; = z^2
(define (square z) (* z z))
; = z^3
(define (cube z) (* z z z))
2.2. Building Procedures Using Application
2.2.1. Example: Coercions
; = symbol made from a vector of chars
(define (vector->symbol char-vector)
(string->symbol
(list->string (vector->list char-vector))))
; = char vector made from a symbol
(define (symbol->vector symbol)
(list->vector
(string->list
(symbol->string symbol)))
; = # yards in m miles
(define (mile->yard m)
(* 1760 m)) ; 1 mile = 1760 yards
; = # feet in y yards
(define (yard->foot y) (* 3 y))
; = #inches in f feet
(define (foot->inch f) (* 12 f))
; = # inches in m miles
(define (mile->inch m)
(foot->inch (yard->foot (mile->yard m))))
2.2.2. Example: Palindromes
; = #t, if string is a palindrome
(define (palindrome? string)
(string-ci=? string (string-reverse string)))
; = reverse of string
(define (string-reverse string)
(list->string (reverse (string->list string))))
2.3. The Abstraction Principle
2.3.1. Constructors
2.3.2. Selectors
2.3.3. Lists as Pairs
(define (cddadr x) (cdr (cdadr x)))
2.3.4. Example: Association Lists as Records
; = record representing a student
(define (make-student name ssn gpa)
(list (cons 'name name)
(cons 'ssn ssn)
(cons 'gpa gpa)))
; = name of student
(define (name student)
(cdar student))
; = social security number of student
(define (ssn student)
(cdadr student))
; = grade point average of student
(define (gpa student)
(cdaddr student))
(define name cdar)
(define ssn cdadr)
(define gpa cdaddr)
(define picard (make-student "Picard" 998869999 3.75))
(define moe (make-student "Moe" 002869999 1.5))
(define spock (make-student "Spock" 905869999 3.9))
; = #t if student's gpa < 2.0
(define (probation? student)
(< (gpa student) 2.0))
; = result of updating student's gpa to new-gpa
(define (update-gpa student new-gpa)
(make-student
(name student) (ssn student) new-gpa))
2.4. Polymorphic Procedures
(define (id val) val) ; the identity procedure
(define (always-0 val) 0)
(define (first val1 val2) val1)
(define (second val1 val2) val2)
(define (make-pair val) (cons val val))
2.4.1. Equivalence Predicates
2.4.2. The not and null? Predicates
(define (unfalse? val) (not (not val)))
2.4.3. Recognition Predicates
2.4.4. Example: Searching Association Lists
(define test1
'(("Picard" . 92) ("Moe" . 34) ("Spock" . 99)))
(define test2
'(("Picard" . 90) ("Moe" . 37) ("Spock" . 100)))
(define test3
'(("Picard" . 89) ("Moe" . 36) ("Spock" . 99)))
(define tests
(list (cons 'test1 test1)
(cons 'test2 test2)
(cons 'test3 test3)))
Graphs
(define string->digit-graph
'(("zero" . 0) ("one" . 1) ("two" . 2)
("three" . 3) ("four" . 4) ("five" . 5)
("six" . 6) ("seven" . 7) ("eight" . 8)
("nine" . 9)))
; = coercion of string to corresponding digit
(define (string->digit string)
(cdr (assoc string string->digit-graph)))
2.5. Meta Procedures
; = average of numbers in the list nums
(define (average nums)
(/ (apply + nums) (length nums)))
; = #t if names is sorted
(define (sorted? names) (apply string-ci<=? names))
; = average score of test
(define (test-avg test)
(average (map cdr test)))
; = #t if for all v in vals (red? v) = #t
(define (all? pred? vals)
(not (member? #f (map pred? vals))))
; = #t if some (pred? v) = #t for some v in vals
(define (some? pred? vals)
(member? #t (map pred? vals)))
(define (member? val vals)
(unfalse? (member val vals)))
; = #t if all members of list vals are characters
(define (char-list? vals)
(all? char? vals))
; = #t if string contains a vowel
(define (contains-vowel? string)
(some? vowel? (string->list string)))
Appendices
Appendix 2.1. Mathematics in Scheme
Arithmetic
Comparing Characters and Strings
Divisibility
; = #t if m divides n
(define (divides? m n)
(zero? (remainder m n)))
Congruence
; = #t if m is congruent to n mod k
(define (congruent? m n k)
(divides? (- m n) k))
; = m + n mod k
(define (mod+ m n k) (modulo (+ m n) k))
; = m * n mod k
(define (mod* m n k) (modulo (* m n) k))
; = m - n mod k
(define (mod- m n k) (modulo (- m n) k))
; = m/n mod k
(define (mod/ m n k) (modulo (quotient m n) k))
; = time h hours after time t
(define (hours+ t h) (mod+ t h 24))
(define (bit+ b1 b2) (mod+ b1 b2 2))
Common Multiples and Divisors
Logs and Exponents
; = log y base x
(define (logt x y) (/ (log y) (log x)))
; = z^(1/n)
(define (nth-root z n) (expt z (/ n)))
Example
; = value of $p investment at rate r after n periods
(define (value p r n)
(* p (expt (+ 1 r) n)))
Trigonometry
; = csc of z radians
(define (csc z) (/ (sin z)))
; = cot of z radians
(define (cot z) ???)
; = sec of z radians
(define (sec z) ???)
(define pi (acos -1)) ; since (cos pi) = -1
Appending Sequences
; = result of adding val to end of vals
(define (cons-last val vals)
(append vals (list val)))
Computing Lengths of Sequences
Extracting Subsequences
; = #t if val is in vals
(define (member? val vals)
(unfalse? (member val vals)))
(define vowels
'(#\a #\A #\e #\E #\i #\I #\o #\O #\u #\U))
(define punctuation '(#\. #\, #\; #\: #\! #\? #\-))
(define (vowel? char)
(member? char vowels))
(define (punctuation? char)
(member? char punctuation))
; = tail of vec beginning at val
(define (vector-member val vec)
(list->vector (member val (vector->list vec))))
; = tail of vec beginning at position pos
(define (vector-tail vec pos)
(list->vector (list-tail (vector->list vec) pos)))
Substrings
; = prefix of string ending at position pos - 1
(define (prefix string pos)
(substring string 0 pos))
; = suffix of string beginning at position pos
(define (suffix string pos)
(substring string pos (string-length string)))
; = #t if string2 is a prefix of string1
(define (prefix? string1 string2)
(string=?
string2
(prefix string1 (string-length string2))))
; = #t if string2 is a suffix of string1
(define (suffix? string1 string2)
(string=?
string2
(suffix
string1
(- (string-length string1)
(string-length string2)))))
Sublists
; = sublist between positions start and (end - 1)
(define (sublist vals start end)
(list-prefix (list-tail vals start)
(- (- end 1) start)))
; = prefix of vals ending at position pos
(define (list-prefix vals pos)
(reverse (list-tail (reverse vals) (- (length vals) (+ pos 1)))))
Other Applications of list-prefix
; = result of removing item at position k from vals
(define (remove vals k)
(append (list-prefix vals (- k 1))
(list-tail vals (+ k 1))))
; = result of inserting item at position pos in vals
(define (insert vals item pos) ???)
; = result of replacing member at
; position pos by item in vals
(define (replace vals item pos) ???)
Optional Parameters
; = average of all parameters
(define (avg . nums) (average nums))
; = #t if all parameters are relatively prime
(define (rel-prime? . ints) (= 1 (apply gcd ints)))
; = #t if all parameters ≠ #f
(define (and? . vals) (all? unfalse? vals))
; = #t if some parameters ≠ #f
(define (or? . vals) (some? unfalse? vals)))
(define (unfalse? val) (not (not val)))
; = #t if b is between a and c
(define (between? a b c)
(or? (<= a b c) (<= c b a)))
; = #t if parameters are sorted
(define (sorted? . strings)
(or? (apply string<? strings)
(apply string<? (reverse strings))))