3

Given a function such as the tree-recursive implementation of the fibonacci recurrence, how could I show each step in the evaluation of an expression such as (fib 5)?

(define (fib n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        (else (+ (fib (- n 1)
                 (fib (- n 2))))))

For example, I would like to output:

(fib 5)

(+ (fib 4) (fib 3))

(+ (+ (fib 3) (fib 2)) (+ (fib 2) (fib 1)))

(+ (+ (+ (+ (fib 1) 0) (fib 1) (+ (fib 1) 0)) (+ (+ (fib 1) 0) (fib 1)))

(+ (+ (+ (+ 1 0) 1 (+ 1 0)) (+ (+ 1 0) 1))

I know that using quasiquoting, you can partially evaluate an expression, as in:

`(+ ,(* 3 4) (- 0.1 2))   ; evaluates to -┐
(+ 12 (- 0.1 2))          ;          <----┘

However, I have not been able to use this to show each step in the evaluation. I know I could modify a scheme interpreter like Peter Norvig's lis.py, but I would like a way to do it within the language itself. How can I do this?

tlehman
  • 5,125
  • 2
  • 33
  • 51

1 Answers1

5

You mean, like this?

(define (fib n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        (else `(+ ,(fib (- n 1))
                  ,(fib (- n 2))))))

For example:

(fib 5)
=> '(+ (+ (+ (+ 1 0) 1) (+ 1 0)) (+ (+ 1 0) 1))

Of course, the above will return only the final result of the evaluation. Using a built-in stepper like the one in Racket, you can see each intermediate step. For a little how-to see this answer, which happens to show the fibonacci function, too.

Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Ah, I was quasiquoting in the wrong place, I kept using it outside the procedure body. Thank you! – tlehman Feb 09 '13 at 16:48
  • I'll have to check out Racket, it looks very cool. What I would like to do is generate a tree visualization like on page 68 of SICP. If I use GraphViz, then I just need to output parent-child pairs, such as "(fib 3) -> (fib 2)", "(fib 3) -> (fib 1)", and use `dot` to render it as a PNG. I could wrap each function call in a (begin (display ..)) statement. – tlehman Feb 09 '13 at 17:01