Questions?
Today we'll walk through some of the ideas in section 1.2 of the textbook.
First, I wanted to point out that the language of this
problem can be confusing. Essentially it asks you to redefine
addition in terms of increment and decrement, in two different ways.
However, since inc
and dec
may be already defined in terms of +
,
redefining +
may also redefine inc
and dec
if you're not careful ...
and this is not what we want.
So I found it easier to think of this as defining new functions, call
them plus-iter and plus-recur, or +'
(plus prime) and +''
(plus double prime)
or whatever you want. That way you won't run the risk of altering inc
and dec
.
One of the methods turns for example 2+3 into 1+4 then into 0+5, stopping when the first is 0, and then keeping the second as the answer.
See the attached images for DrRacket trace versions of the factorial 'n!' implemented in two different way. Discuss what the "last" thing that happens is, and why one can use "tail recursion" but the other cannot.
In our terminal version of Guile, I've found
that if you define factorial in a file and
then (load "factorial.scm")
, the trace
is long and uses compiler-assigned unfriendly names.
To see this "iterative process" vs "recursive process"
version, it works to define the function at the
interactive prompt and then trace that :
$ scheme
Guile 2.2.7. Enter ',help' for help.
Language: scheme for SICP with some extras.
> (define (factorial n)
... (if (= n 1)
... 1
... (* n (factorial (- n 1)))))
> ,trace (factorial 6)
trace: (factorial 6)
trace: | (factorial 5)
trace: | | (factorial 4)
trace: | | | (factorial 3)
trace: | | | | (factorial 2)
trace: | | | | | (factorial 1)
trace: | | | | | 1
trace: | | | | 2
trace: | | | 6
trace: | | 24
trace: | 120
trace: 720
>
Compare that "shape" with this :
$ scheme
Guile 2.2.7. Enter ',help' for help.
Language: scheme for SICP with some extras.
> (define (fact-iter answer counter n)
... (if (> counter n)
... answer
... (fact-iter (* counter answer)
... (+ counter 1)
... n)))
> ,trace (fact-iter 1 1 6)
trace: (fact-iter 1 1 6)
trace: (fact-iter 1 2 6)
trace: (fact-iter 2 3 6)
trace: (fact-iter 6 4 6)
trace: (fact-iter 24 5 6)
trace: (fact-iter 120 6 6)
trace: (fact-iter 720 7 6)
trace: 720
>
Let's first discuss this in python to make clear the differences in approach ... what's good and what works.
last modified | size | ||
factorial_iter.png | Mon Sep 13 2021 01:04 am | 293K | |
factorial_recur.png | Mon Sep 13 2021 01:04 am | 257K |