[plt-scheme] Another continuation question
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