(define trace--indent " ")
(define-syntax trace-define
(syntax-rules ()
((_ (name args ...) body ...)
(define (name args ...)
(for-each display (list trace--indent "(" (quote name)))
(for-each display (list " " args)) ...
(display ")\n")
(let ((old-indent trace--indent)
(return
(begin
(set! trace--indent (string-append trace--indent ": "))
body ...)))
(set! trace--indent old-indent)
(unless (equal? trace--indent " ")
(for-each display (list trace--indent return "\n")))
return)))))
(define-syntax trace-lambda
(syntax-rules ()
((_ name (args ...) body ...)
(lambda (args ...)
(trace-define (name args ...) body ...)
(name args ...)))))
(define-syntax trace-let
(syntax-rules ()
((_ name ((keys values) ...) body ...)
((lambda ()
(trace-define (name keys ...) body ...)
(name values ...))))))
(define-syntax trace
(syntax-rules ()
((_ exp)
(let ((result exp))
(for-each display (list trace--indent result "\n"))
result))))