To describe it, here is the small piece of code which causes the problem.
(import (rnrs)) (define label-counter (lambda () 0)) (define (new-lbl!) (label-counter)) (define (change-label-counter) (set! label-counter (lambda () 1))) (define (print . args) (for-each display args) (newline)) (let ((lbl (new-lbl!))) (print lbl)) (change-label-counter) (let ((lbl (new-lbl!))) (print lbl))This should print 0 then 1. Well, it doesn't seem there is a problem except the
change-label-counter. The defined
label-counteris obviously constant so it'd be inlined in the
new-lbl!. Now, the
change-label-countersets the new value to
label-counter, here comes the problem. The
new-lbl!has already compiled with inlined value and just returns 0 so
change-label-counterdoesn't have any effect to it. Then the result value would be always 0.
If these procedures are defined in a library, then Sagittarius compiler could check if the global defined variable would be changed or not however because this is defined in a script it can't and just tries to inline so that the target procedure looks constant.
What I can do is;
- Don't inline them if it's in script.
set!for globally defined variable.
- Make impossible to run some of R5RS code (e.g. Gambit benchmark's compiler)
- Read all expression and wrap with a library before compiling a script
- I can already see the horrible future...