[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Chicken-hackers] Another bug from the net
From: |
Thomas Bushnell BSG |
Subject: |
[Chicken-hackers] Another bug from the net |
Date: |
Tue, 21 Jul 2009 00:23:54 -0700 |
Chicken gets this wrong:
(let ((cont #f))
(letrec ((x (call-with-current-continuation (lambda (c) (set! cont c) 0)))
(y (call-with-current-continuation (lambda (c) (set! cont c) 0))))
(if cont
(let ((c cont))
(set! cont #f)
(set! x 1)
(set! y 1)
(c 0))
(+ x y))))
Should be 0, but I get 1 in Chicken 3.4.
Discussion was at
http://groups.google.com/group/comp.lang.scheme/msg/306ccb44cd2ab7e5.
The proper order of evaluation of letrec goes:
1) establish binding for both variables
2a) evaluate initializer for first variable, stash value away
2b) evaluate initializer for second variable, stash value away
3) set both variables to stashed values
The first time through, x and y get bound and then set to 0, and cont is set to
one or the other continuation (doesn't matter which). Then we set x and y
both to 1, and invoke the continuation.
The continuation must be the one we saved in step 2b above. It returns 0, and
then both variables should get set to 0 by step 3, but clearly (since 1 is being
returned) the variable evaluated in step 2a doesn't get reset properly.
This typically happens because the compiler doesn't actually stash the values
away,
but instead sees that they don't involve any recursion (the usual letrec
issue), and
simply sets them one at a time. In other words, what seems to be happening in
Chicken is
1) establish bindings
2a) evaluate first initializer, set variable
2b) evaluate second initializer, set variable
which is quite incorrect.
Thomas
- [Chicken-hackers] Another bug from the net,
Thomas Bushnell BSG <=