With guile 2.0.11: scheme@(guile-user)> (use-modules (ice-9 control)) scheme@(guile-user)> (list 'a (let/ec ae (list 'b (let/ec be (be 2))))) $1 = (a (b 2)) scheme@(guile-user)> (list 'a (let/ec ae (list 'b (let/ec be (ae 2))))) $2 = (a (b 2)) scheme@(guile-user)> (list 'a (let/ec ae (list 'b (ae 2)))) $3 = (a 2)
The middle of these three cases is wrong: it attempts to invoke the outer escape continuation, but only goes as far as the target of the inner one, which it isn't using. It therefore produces the same result as the first case, which invokes the inner escape continuation. It ought to behave like the third case, which shows that the outer escape continuation can be successfully invoked when the unused inner continuation is not present. The problem only affects let/ec, *not* call/ec: scheme@(guile-user)> (list 'a (call/ec (lambda (ae) (list 'b (call/ec (lambda (be) (be 2))))))) $4 = (a (b 2)) scheme@(guile-user)> (list 'a (call/ec (lambda (ae) (list 'b (call/ec (lambda (be) (ae 2))))))) $5 = (a 2) scheme@(guile-user)> (list 'a (call/ec (lambda (ae) (list 'b (ae 2))))) $6 = (a 2) It also only happens when compiling, not when interpreting: scheme@(guile-user)> ,o interp #t scheme@(guile-user)> (list 'a (let/ec ae (list 'b (let/ec be (be 2))))) $7 = (a (b 2)) scheme@(guile-user)> (list 'a (let/ec ae (list 'b (let/ec be (ae 2))))) $8 = (a 2) scheme@(guile-user)> (list 'a (let/ec ae (list 'b (ae 2)))) $9 = (a 2) -zefram