Next: , Previous: , Up: Top   [Index]


18 Tracing syntaxes

Procedure: make-traced-procedure name proc

The procedure make-traced-procedure takes a name (typically a symbol) and a procedure. It returns a procedure similar to proc except that it traces its arguments and values.

> (define (fact n)
    (if (zero? n)
        (lambda (k) (k 1))
        (lambda (k)
          ((fact (- n 1))
           (make-traced-procedure `(k ,n)
             (lambda (v)
               (k (* v n))))))))
> (call/cc
    (lambda (k)
      ((fact 5) (make-traced-procedure 'K k))))
|((k 1) 1)
|((k 2) 1)
|((k 3) 2)
|((k 4) 6)
|((k 5) 24)
|(K 120)
120
Syntax: trace-define (?name . ?args) ?body0 ?body
Syntax: trace-define ?name ?expression

The trace-define syntax is similar to define except that the bound value, which must be a procedure, becomes a traced procedure. A traced procedure prints its arguments when it is called and prints its values when it returns.

> (trace-define (fact n)
    (if (zero? n) 1 (* n (fact (- n 1)))))
> (fact 5)
|(fact 5)
| (fact 4)
| |(fact 3)
| | (fact 2)
| | |(fact 1)
| | | (fact 0)
| | | 1
| | |1
| | 2
| |6
| 24
|120
120

The tracing facility in Vicare preserves and shows tail recursion and distinguishes it from non–tail recursion by showing tail calls starting at the same line in which their parent was called.

> (trace-define (fact n)
    (trace-define (fact-aux n m)
      (if (zero? n) m (fact-aux (- n 1) (* n m))))
    (fact-aux n 1))
> (fact 5)
|(fact 5)
|(fact-aux 5 1)
|(fact-aux 4 5)
|(fact-aux 3 20)
|(fact-aux 2 60)
|(fact-aux 1 120)
|(fact-aux 0 120)
|120
120

Moreover, the tracing facility interacts well with continuations and exceptions.

> (call/cc
    (lambda (k)
      (trace-define (loop n)
        (if (zero? n)
            (k 'done)
            (+ (loop (- n 1)) 1)))
      (loop 5)))
|(loop 5)
| (loop 4)
| |(loop 3)
| | (loop 2)
| | |(loop 1)
| | | (loop 0)
done
Syntax: trace-lambda ?name ?args ?body0 ?body

The trace-lambda macro is similar to lambda except that the resulting procedure is traced: it prints the arguments it receives and the results it returns.

Syntax: trace-define-syntax ?keyword ?expression

Like define-syntax but create a tracing transformer function. Whenever the macro is expanded the transformer function will print its argument (the input form) and its return value (the output form). Example:

(trace-define-syntax ciao
  (syntax-rules ()
    ((_ ?a)
     (list 1 ?a 3))))

(ciao 2)
-| |(ciao (ciao 2))
-| |(list 1 2 3)

the first printed symbolic expression (ciao (ciao 2)) shows the called tranformer function (ciao ---) and its argument being the input form (ciao 2), filtered through syntax->datum.

Syntax: trace-let-syntax ?bindings ?form
Syntax: trace-letrec-syntax ?bindings ?form

Like let-syntax and letrec-syntax but define tracing transformer functions.


Next: , Previous: , Up: Top   [Index]