Next: , Previous: Trap Context, Up: Traps


5.21.3.5 Tracing Examples

The following examples show what tracing is and the kind of output that it generates. In the first example, we define a recursive function for reversing a list, then watch the effect of the recursive calls by tracing each call and return value.

     guile> (define (rev ls)
              (if (null? ls)
                  ls
                  (append (rev (cdr ls))
                          (list (car ls)))))
     guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
     guile> (define t1 (make <procedure-trap>
                         #:procedure rev
                         #:behaviour (list trace-trap
                                           trace-at-exit)))
     guile> (install-trap t1)
     guile> (rev '(a b c))
     |  2: [rev (a b c)]
     |  3: [rev (b c)]
     |  4: [rev (c)]
     |  5: [rev ()]
     |  5: =>()
     |  4: =>(c)
     |  3: =>(c b)
     |  2: =>(c b a)
     (c b a)

The number before the colon in this output (which follows (ice-9 debugging trace)'s default output format) is the number of real frames on the stack. The fact that this number increases for each recursive call confirms that the implementation above of rev is not tail-recursive.

In the next example, we probe the internal workings of rev in more detail by using the trace-until-exit behaviour.

     guile> (uninstall-trap t1)
     guile> (define t2 (make <procedure-trap>
                         #:procedure rev
                         #:behaviour (list trace-trap
                                           trace-until-exit)))
     guile> (install-trap t2)
     guile> (rev '(a b))
     |  2: [rev (a b)]
     |  2: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
     |  3: (null? ls)
     |  3: [null? (a b)]
     |  3: =>#f
     |  2: (append (rev (cdr ls)) (list (car ls)))
     |  3: (rev (cdr ls))
     |  4: (cdr ls)
     |  4: [cdr (a b)]
     |  4: =>(b)
     |  3: [rev (b)]
     |  3: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
     |  4: (null? ls)
     |  4: [null? (b)]
     |  4: =>#f
     |  3: (append (rev (cdr ls)) (list (car ls)))
     |  4: (rev (cdr ls))
     |  5: (cdr ls)
     |  5: [cdr (b)]
     |  5: =>()
     |  4: [rev ()]
     |  4: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
     |  5: (null? ls)
     |  5: [null? ()]
     |  5: =>#t
     |  4: (list (car ls))
     |  5: (car ls)
     |  5: [car (b)]
     |  5: =>b
     |  4: [list b]
     |  4: =>(b)
     |  3: [append () (b)]
     |  3: =>(b)
     |  3: (list (car ls))
     |  4: (car ls)
     |  4: [car (a b)]
     |  4: =>a
     |  3: [list a]
     |  3: =>(a)
     |  2: [append (b) (a)]
     |  2: =>(b a)
     (b a)

The output in this case shows every step that the evaluator performs in evaluating (rev '(a b)).