private: No


(define-library (debug trace)
  (export trace-define trace-lambda trace-let trace)
  (import (scheme base) (scheme write))
  (begin
    (define global-indent " ")

    (define-syntax trace-define
      (syntax-rules ()
        ((_ (name args ...) body ...)
         (define (name args ...)
           (let ((indent global-indent))
             (display indent)
             (display "(")
             (display (quote name))
             (begin (display " ") (display args))
             ...
             (display ")")
             (newline)
             (set! global-indent (string-append indent ": "))
             (let ((return body ...))
               (set! global-indent indent)
               (unless (equal? indent " ")
                 (display indent)
                 (display return)
                 (newline))
               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 () ; why doesn't ‘begin’ work?
          (trace-define (name keys ...) body ...)
          (name values ...))))))

    (define-syntax trace
      (syntax-rules ()
        ((_ exp)
         (let ((result exp))
           (display global-indent)
           (display result)
           (newline)
           result))))))