masak / bel

An interpreter for Bel, Paul Graham's Lisp language
GNU General Public License v3.0
26 stars 1 forks source link

Something is wrong when using 'trace' on '+' and then calling 'reduce' #437

Open masak opened 1 year ago

masak commented 1 year ago

I haven't been able to find the root cause here, but I can show the symptom pretty well. The following works as intended:

$ perl -Ilib bin/bel
Language::Bel 0.63 -- msys.
> (set old-+ +)
(lit clo nil ns (foldr (fn (x y) (apply buildnum ((of c+ cddr) x y))) 0 ns))
> (def + (n1 n2) (pr "(+ " n1 " " n2 ")" \lf) (old-+ n1 n2))
> (reduce + '(1 2 3 4 5))
(+ 4 5)
(+ 3 9)
(+ 2 12)
(+ 1 14)
15

Pretty cool, eh?

And then the following doesn't:

(def prlf args
  (atomic
    (apply pr args)
    (pr \lf)))

(set wrapped-fns-table (table))

(mac wrap (f w)
  (letu (vf vw)
    `(withs (,vf ,f
             ,vw ,w
             w2 (fn args (apply ,vw (cons ,vf args))))
       (set (wrapped-fns-table w2) ,vf
            ,f w2))))

(set *trace-depth* 0)

(mac trace (f)
  `(wrap ,f
         (fn (orig . args)
           (repeat *trace-depth* (pr "  "))
           (pr "Entering (" (nom ',f))
           (each a args
             (pr " " a))
           (prlf ")")
           (++ *trace-depth*)
           (let result (apply orig args)
             (-- *trace-depth*)
             (repeat *trace-depth* (pr "  "))
             (pr "Leaving " (nom ',f))
             (prlf " ==> " result)
             result))))

(trace +)

(reduce + '(1 2 3 4 5))

Gives the following output:

$ perl -Ilib bin/bel trace-plus.bel
Entering (+ 4 5)
Entering (+ 0 1)
Entering (+ 0 1)
Entering (+ 0 1)
Entering (+ 0 1)

I see three things that are wrong, offhand:

Even though I haven't confirmed it, I suspect this is another re-occurrence of #273. Somehow.