[gambit-list] Continuations bug in v4.6.2?

Marc Feeley feeley at iro.umontreal.ca
Mon Dec 9 23:29:58 EST 2013


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

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

When evaluation is left-to-right (which is not required by the standard, but is common) the expression (f (g x)) is evaluated as though it was

  (let ((t1 f)) ;; get value of f
    (let ((t2 g)) ;; get value of g
      (let ((t3 x)) ;; get value of x
        (let ((t4 (t2 t3))) ;; call (g x)
          (t1 t4))))) ;; call (f (g x))

The expression (let ((temp (g x))) (f temp)) forces a different order, namely

  (let ((t1 g)) ;; get value of g
    (let ((t2 x)) ;; get value of x
      (let ((t3 (t1 t2))) ;; call (g x)
        (let ((t4 f)) ;; get value of f
          (t4 t3))))) ;; call (f temp)

In your code, this makes a difference because f (which is "return-point" in your code) is being mutated during the evaluation of the call to g.

In your "version 1", the function originally bound to return-point will be called (i.e. the continuation of the function make-jp).  In your "version 2", the function bound to return-point by the call to (block jp) will be called (i.e. the continuation of the call (y 0)).

Marc




More information about the Gambit-list mailing list