I am developing the semantics for a formulation of coroutines that I've been working on. In vague-ish english words, make-jp returns a "callable thing", which I am calling a "jump point". Every time that a "jump point" is called, execution jumps to the last place where the jump-point was invoked. 

If Bigloo, Chicken, and Gambit all behave the same way then I think you are probably right and that this is proper behavior. 

However, this leaves me feeling deeply disturbed. I feel that 

(f (g x))

should *always* be absolutely equivalent to:

(let [(temp (g x))]
   (f temp))

My example indicates that this is not necessarily the case. Are there other situations where this is not true? I suspect that I don't quite understand the interaction between tail-calls and continuations properly.

  -Patrick


On Mon, Dec 9, 2013 at 7:50 PM, Marc Feeley <feeley@iro.umontreal.ca> wrote:
I tried your code with Bigloo, Chicken and Gambit.  All three systems give the same result, so I doubt there is a bug.  Perhaps you can explain what you are trying to achieve.

Marc

On Dec 9, 2013, at 10:10 PM, Patrick Li <patrickli.2001@gmail.com> wrote:

> Hello!
>
> I've been writing some tricky code involving continuations, and ran into the
> following surprising behavior from Gambit v.4.6.2 running on OSX.
>
> I have two versions of "make-jp", that I believe should be
> equivalent.
>
>    Version 1:
>       (define (make-jp block)
>         (let [(return-point '())]
>           (call/cc (lambda (ret)
>             (define (jp x)
>               (call/cc (lambda (ret)
>                  (let [(r return-point)]
>                    (set! return-point ret)
>                    (r x)))))
>             (set! return-point ret)
>             (let [(result (block jp))]
>               (return-point result))))))
>
>    Version 2:
>       (define (make-jp block)
>         (let [(return-point '())]
>           (call/cc (lambda (ret)
>             (define (jp x)
>               (call/cc (lambda (ret)
>                  (let [(r return-point)]
>                    (set! return-point ret)
>                    (r x)))))
>             (set! return-point ret)
>             (return-point (block jp))))))
>
> The only difference is the final line:
>
>    Version 1:
>       (let [(result (block jp))]
>         (return-point result))
>
>    Version 2:
>       (return-point (block jp))
>
>
> However, I get different behavior when I test with the following code:
>
>    Testing Code:
>       (let* [(j '())]
>         (make-jp (lambda (y)
>            (set! j y)
>            (y 0)
>            10))
>         (println "GOT: " (j "X")))
>
>    Version 1 prints:
>       GOT: 10
>
>    Version 2 prints:
>       GOT: X
>
> Out of the two behaviours, I expect the answer given by Version 1.
>
> Can anyone verify whether this is a bug, and whether the latest
> version also shows this behavior?  This fell out of a piece of code
> I'm using to simulate coroutines for an interpreter that I am
> programming. Here I've tried to isolate the problem down to as few
> lines as possible.
>
> Once I get my environment fixed, I will try it on the latest version
> of Gambit as well and see if the problem is still there.
>
>   -Patrick
>
> _______________________________________________
> Gambit-list mailing list
> Gambit-list@iro.umontreal.ca
> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list