[plt-scheme] Another continuation question

From: Anton van Straaten (anton at appsolutions.com)
Date: Sat Jul 19 17:53:28 EDT 2008

Grant Rettke wrote:
> In a thread that I can't find, I'm pretty sure that Matthias posted
> some interesting "self modifying code" that looked like this, which I
> found on:
> 
> http://en.wikipedia.org/wiki/Call-with-current-continuation
> 
> ;; [LISTOF X] -> ( -> X u 'you-fell-off-the-end-off-the-list)
> (define (generate-one-element-at-a-time a-list)
>   ;; (-> X u 'you-fell-off-the-end-off-the-list)
>   ;; this is the actual generator, producing one item from a-list at a time
>   (define (generator)
>     (call/cc control-state))
>   ;; [CONTINUATION X] -> EMPTY
>   ;; hand the next item from a-list to "return" (or an end-of-list marker)'
>   (define (control-state return)
>     (for-each
>      (lambda (an-element-from-a-list)
>        (call/cc
>         (lambda (resume-here)
>           (set! control-state resume-here)
>           (return an-element-from-a-list))))
>      a-list)
>     (return 'you-fell-off-the-end-off-the-list))
>   ;; time to return the generator
>   generator)
> 
> (define gen (generate-one-element-at-a-time '(a b c)))
> (gen)
> (gen)
> (gen)
> (gen)
> 
> This is another chunk of code that worked fine in v372, and per the
> thread [Confusing continuation behavior (a question about)], I suspect
> that the code shouldn't have worked, because now it goes into an
> endless loop?

That's right.  As with your example, this code had a bug in that it only 
worked when a function like 'gen' was invoked from the top level.

Matthias later fixed this bug in the code that he had posted.  So one 
way to solve the problem is to find where he published that fix.  But 
that would be cheating!

The issues above are the same as I pointed out for the previous example. 
  When 'gen' is invoked for the second and subsequent times, the value 
of 'return' isn't updated, because the control-state continuation jumps 
into the middle of the procedure passed to for-each.  So 'return' always 
returns to after the first call to 'gen'.

The fix will involve updating 'return' appropriately.

To recap the important questions:

1. When (call/cc control-state) is evaluated on the second call to gen, 
what value is passed to the continuation stored in control-state?  Might 
it be useful?  What happens to that value?

2. When (call/cc (lambda (resume-here) ...) is evaluated inside the 
for-each, what is the result of that expression?  Might it be useful? 
What happens to that value?

3. Is there any relationship between the values discussed in #1 and #2?

Anton



Posted on the users mailing list.