views:

69

answers:

1

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?

+6  A: 

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.

erjiang