[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

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 
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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]