debug-print

どの出力がどの expression のどの評価 instance に対応するのか default では非常にわかりにくいから改造。file:line 情報を出すにはもう一つ下の interface を使うことになりそう。まあとりあえずこれでいいか。
しかし何でもアリだな syntactic closure て。gensym がめんどいけど。

(define-macro debug-print
  (let ((id 0)) ; Instance ID.
    (lambda (expr)
      (inc! id)
      (let* ((act-id 0) ; Activation ID.
             (next-act-id! (lambda () (inc! act-id)))
             (act-id-name (gensym))
             (tmp (gensym)))
        `(let ((,act-id-name (,next-act-id!)))
           (display (format "#?=~s:~s  ~s~%" ,id ,act-id-name ',expr)
                    (current-error-port))
           (let ((,tmp ,expr))
             (display (format "#?-~s:~s> ~s~%"
                              ,id ,act-id-name ,tmp)
                      (current-error-port))
             ,tmp)
           )))))
(use util.match)
(display
 (let fact-and-sum ((n 3))
   (if (= n 0)
      (cons 1 0)
      (match #?=(fact-and-sum (- #?=n 1))
        ((f . s) (cons (* n f) (+ n s)))))))
    • > 出力
#?=1:1  (fact-and-sum (- (debug-print n) 1))
#?=2:1  n
#?-2:1> 3
#?=1:2  (fact-and-sum (- (debug-print n) 1))
#?=2:2  n
#?-2:2> 2
#?=1:3  (fact-and-sum (- (debug-print n) 1))
#?=2:3  n
#?-2:3> 1
#?-1:3> (1 . 0)
#?-1:2> (1 . 1)
#?-1:1> (2 . 3)
(6 . 6)