I received an unexpected result when redefining the +
operator in a scheme program using guile
. I should point out that this occurred while experimenting to try to understand the language; there's no attempt here to write a useful program.
Here's the code:
(define (f a b) 4)
(define (show)
(display (+ 2 2)) (display ",") (display (f 2 2)) (newline))
(show)
; guile & mit-scheme: "4,4"
(define (+ a b) 5)
(define (f a b) 5)
(show)
; mit-scheme: "5,5"
; guile: "4,5" - this "4" is the unexpected result
(define (show)
(display (+ 2 2)) (display ",") (display (f 2 2)) (newline))
(show)
; guile & mit-scheme: "5,5"
In guile
the function show
uses the predefined definition of +
even after I've redefined it, though it uses the new definition of f
. I have to redefine show
to get it to recognise the new definition of +
. In mit-scheme
both new definitions are recognised immediately, which is what I was expecting to happen. Also, any further definitions of +
are instantly recognised by both interpreters without having to redefine show
.
What's going on behind the scenes in guile
to make it bind references to these redefined operators differently?
And why the difference between the two interpreters?
It looks like Guile is wrongly assuming that nobody is crazy enough to redefine +
and is making the optimization of folding (+ 2 2) => 4
, making (display (+ 2 2))
become (display 4)
. That would explain why you need to redefine show
in order to reflect your new +
.
Indeed, if you first do (define (+ a b) 4)
at the very top of your program, Guile will not do that optimization and you will get 4,4
and 5,5
just like MIT Scheme.
Edit: Actually, it looks like Guile will optimize +
to reference its own native +
construct, meaning that even if you don't use constants (no constant folding) you will still be unable to redefine +
like that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With