This preview shows pages 1–3. Sign up to view the full content.
Sheet1
Page 1
CS61AWeek 14 solutions
HOMEWORK:

4.25
UNLESS in normal vs. applicative order
In ordinary (applicative order) Scheme, this version of FACTORIAL
will be an infinite loop, because the argument subexpression
(* n (factorial ( n 1))) is evaluated before UNLESS is called,
whether or not n is 1.
In normal order Scheme it'll work fine, because the argument
subexpressions aren't evaluated until they're needed.
What
will actually happen is that each use of the special form IF
within UNLESS will force the computation of (= n 1), but
no multiplications will happen until the evaluator tries to
print the result.
In effect, (factorial 5) returns the thunk
(lambda () (* 5 (* 4 (* 3 (* 2 (* 1 1))))))
and that gets evaluated just in time to print the answer.
4.26
Normal order vs. special forms
For Ben's side of the argument we must implement UNLESS as a
derived expression:
(define (unless>if exp)
(makeif (unlesspredicate exp)
(unlessconsequent exp)
(unlessalternative exp)))
(define unlesspredicate cadr)
(define unlessalternative caddr)
(define unlessconsequent cadddr)
Notice that we reversed the order of the last two subexpressions in
the call to makeif.
Then we just add a clause
((unless? exp) (eval (unless>if exp) env))
to the ordinary metacircular evaluator, or
((unless? exp) (analyze (unless>if exp)))
to the analyzing evaluator.
For Alyssa's side of the argument, we need a case in which it's useful
to
have a Scheme special form available as an ordinary procedure.
The
only
thing we can do with ordinary procedures but not with special forms is
use
This preview has intentionally blurred sections. Sign up to view the full version.
View Full Document
Page 2
them as arguments to higherorder procedures.
An example using UNLESS
will
be a little strained, so first we'll look at a more common situation
involving a different special form, namely AND.
We'd like to be able
to say
(define (alltrue? tflist)
(accumulate and tflist))
Now, here's the strained example using UNLESS:
Suppose we have a list
of
truefalse values and we'd like to add up the number of true ones.
Here's a
somewhat strange way to do it:
(define zerolist (cons 0 '()))
(setcdr! zerolist zerolist)
(define onelist (cons 1 '()))
(setcdr! onelist onelist)
(define (howmanytrue tflist)
(apply + (map unless tflist zerolist onelist)))
Zerolist is an infinite list of zeros
of ones.
We make use of the fact that MAP's end test is that its
first argument is empty, so MAP will return a list the same size as
the argument tflist.
For example, if tflist is
(#t #t #f #t)
then map will return
(1 1 0 1)
created, in effect, this way:
(list (unless #t 0 1)
(unless #t 0 1)
(unless #f 0 1)
(unless #t 0 1))
And so + will return 3, the number of trues in the list.
4.28
Why force the operator of a combination?
This is the end of the preview. Sign up
to
access the rest of the document.
 Spring '08
 mckenzie

Click to edit the document details