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]