6.001 Recitation #7 Feb 26, 2003
RI: Konrad Tollmar
Programming practice
Common
Sources of (Scheme) Errors
Typographical errors (misspellings)
Syntax
errors (parens)
Errors
inside a module (procedure or algorithm)
Errors
connecting modules together (program structure)
Unbound or unassigned variable
Either a
typographical error, or use of a variable outside of the part of the program in
which it is available (e.g. using a
variable
created by let outside the body of the let, or use of a variable created by
define within a procedure outside of
that
procedure).
Applying something that isn't a procedure
"The
object ... is not applicable" The value of the first subexpression in a
combination must be a procedure.
Wrong
number of arguments to a procedure The number of arguments in a call to a
procedure must
match
the number of parameters the procedure expects.
Wrong
type or range of arguments to a primitive procedure
Some
primitive procedures require a specific type of argument.
Numerical errors (overflow, underflow, divide by zero)
The
numerical procedures can fail in a number of ways when dealing with inexact
numbers that are either very large, very small, or very close to zero.
Other
errors
A number
of the procedures built into MIT Scheme can detect special errors and report
them. For example, "Unable to open file ... because: no such file or
directory."
Pretty
printer
Debugger
Tracing
Breakpoints
Don't
throw away your state when an error occurs
Think
abstractly to locate a module that is failing
Examine only modules that fail
Errors
are more common in connecting modules together than in individual modules
3. Let
Use let to write a procedure that compute
a = 1 + xy; b = 1 - y; f(x,y) = a2x + by + ab
(define (f x y)
(define (f-helper a b)
(+ (* x (square a))
(* y b)
(* a b)))
(f-helper (+ 1 (* x y))
(- 1 y)))
(define (f x y)
((lambda (a
b)
(+ (* x
(square a))
(* y
b)
(* a
b)))
(+ 1 (* x
y))
(- 1
y)))
(define (f x y)
(let ((a (+
1 (* x y))
(b (-
1 y)) )
(+ (*
x (square a))
(* y b)
(*
a b))))
Let*
evaluates and binds each
name/value pair in
sequence, so that
each definition is available to the next
(let* ((x 1)
(y 2)
(z (+
x y))
z)
=== 3!
x
=> (())
y
=> (1 2 3)
z
=> (1 (2 3) ((4)))
w
=> (1 2 3 4 5)
(define (filter pred lst)
(cond ((null? lst) nil)
((pred (car lst))
(cons (car lst) (filter pred (cdr lst))))
(else (filter pred (cdr lst)))))
(define (accumulate op init lst)
(if (null? lst)
init
(op (car lst)
(accumulate op init (cdr lst)))))
(map (lambda (x) (cons x
nil)) y) -> ((1) (2) (3))
(map inc w) -> (2 3 4
5 6)
(filter odd? w) -> (1 3 5)
(map inc (filter odd? w))
-> (2 4 6)
(filter odd? (map inc w))
-> (3 5)
(accumulate + 0 (map inc
(filter odd? w))) -> 12
5. What are the types of these procedures?
1. length
List<A>->number
2. list-ref
List<A>,number->A
3. map
(A->B),List<A>->List<B>
4. filter
(A->boolean),List<A>->List<A>
5. accumulate
(A,B->B),B,List<A>->B
5b. Trees
Type Definition:
Tree<C>
= List<Tree<C>> | Leaf<C>
Leaf<C>
= C
Operations:
leaf?
countleaves,
scaletree, enum-leaves, map-tree & tree-ref
Flatten tree to
list of leaves:
(enumerate-leaves (list 1 (list 3 4 5)(list 2 30)))
==> (1 3 4 5 2 30)
(define (e-l x)
(cond
((null? x) nil)
((not (pair? x)) (list x))
(else (append (e-l (car x))
(e-l (cdr x))))))
(define comp
(lambda (a b)
(lambda (x)
(if x a
b)))
)