Search code examples
debugginglispracketsicpdr.racket

How to debugg iterative procedures?


I am using Dr. Racket and Racket for educational purposes (studying the SICP book). Dr. Racket is great and it has an awesome tool called "trace".

After using:

(require trace/racket)
(trace function)

It is possible to see what is happening in a recursive procedure.

However, this feature does not work with iterative procedures. I wish I could "see" what's happening in my code while it is being executed. I wish I could see the change in values of the state variables.

Is there an alternative tool or practice to have that kind of information in an iterative procedure?


Solution

  • Tracing is not debugging. In DrRacket you press the DEBUG button and right click on the edge of interesting parts, like a if that determines base case or defautl case in a helper and choose "Pause at this point". Then everytime you hit Go you can see the bound arguments a step at a time.

    If you want to just trace you can trace a helper like this:

    (require racket/trace)
    (define (reverse lst)
      (define (aux lst acc)
        (if (null? lst)
            acc
            (aux (cdr lst)
                 (cons (car lst) acc))))
      (trace aux) ; tracing the helper
      (aux lst '()))
    
    (reverse '(1 2 3 4))
    
    >(aux '(1 2 3 4) '())
    >(aux '(2 3 4) '(1))
    >(aux '(3 4) '(2 1))
    >(aux '(4) '(3 2 1))
    >(aux '() '(4 3 2 1))
    <'(4 3 2 1)
    ;==> (4 3 2 1)
    

    If you want to use named let just replace it with trace-let:

    (define (reverse lst)
      ;; TODO: Put back to let
      (trace-let aux ((lst lst) (acc '()))
        (if (null? lst)
            acc
            (aux (cdr lst)
                 (cons (car lst) acc)))))
    

    Using the debugger is much faster than having to add lines and remove lines in code in order to test it.