Hi!
Suppose I have a.scm with next code: ;;------------------------------------------ (define l #f)
(let ((t 0)) (set! l (lambda (q) (pp t) (set! t q)))) ;;------------------------------------------
Then I start gsc and do next things:
Gambit v4.5.1
(load "a.scm")
".../a.scm"
(l 2)
0
(l 3)
2
(compile-file "a.scm") (load "a")
".../a.o1"
(l 2)
0 #&2
(l 3)
2 #&3
Why in compiled code set! returns boxed value, but in interpreted code not?
Vasil
Afficher les réponses par date
On 30-Aug-09, at 8:46 AM, vasil wrote:
Hi!
Suppose I have a.scm with next code: ;;------------------------------------------ (define l #f)
(let ((t 0)) (set! l (lambda (q) (pp t) (set! t q)))) ;;------------------------------------------
Then I start gsc and do next things:
Gambit v4.5.1
(load "a.scm")
".../a.scm"
(l 2)
0
(l 3)
2
(compile-file "a.scm") (load "a")
".../a.o1"
(l 2)
0 #&2
(l 3)
2 #&3
Why in compiled code set! returns boxed value, but in interpreted code not?
Vasil
In Scheme "The result of the `set!' expression is unspecified." In the interpreter `set!' returns the #!void object, for which the REPL does not produce any output. The compiler introduced a cell ("box" type) to store the value of t, and transformed (let ((t 0))... into (let ((t (box 0))... and (set! t q) into (set-box! t q). And the set- box! procedure returns the box that was set, so that's what `set!' returns in compiled code.
I could change the implementation of set-box! so that it returns #! void, and then the result of the compiler and interpreter would be the same. This will probably have a (very) small impact on performance.
On the other hand, you should be careful in general to avoid relying on a particular result when the standard indicates that the result is unspecified, and this happens in several places in the standard.
Marc
Marc Feeley wrote:
In Scheme "The result of the `set!' expression is unspecified." In the interpreter `set!' returns the #!void object, for which the REPL does not produce any output. The compiler introduced a cell ("box" type) to store the value of t, and transformed (let ((t 0))... into (let ((t (box 0))... and (set! t q) into (set-box! t q). And the set-box! procedure returns the box that was set, so that's what `set!' returns in compiled code.
I could change the implementation of set-box! so that it returns #!void, and then the result of the compiler and interpreter would be the same. This will probably have a (very) small impact on performance.
Thanks for reply!
Do not bother with this, Marc.
I never use results from functions with unspecified result in my code.
Just suddenly found difference in behavior of compiled and interpreted code, and that is why I asked the question.
Vasil