I have just started learning scheme using and got pretty confused when I reached call-with-current-continuation.
After reading up on Wikipedia (http://en.wikipedia.org/wiki/Call-with- current-continuation) I think I've got some idea of how what call/cc is. But I'm still a bit confused by the example given:
Basically, what's confusing me is line 9 - why is "return" getting set! at this point? And how can it be? Won't the continuation jump out of the current context so it no longer continues?
On Oct 21, 9:53 am, the.brown.dragon.b...@gmail.com wrote:
> Basically, what's confusing me is line 9 - why is "return" getting > set! at this point? And how can it be? Won't the continuation jump out > of the current context so it no longer continues?
You calling 'return' and not the continuation. Unless you call 'resume-here', the procedure will always exit, and set! 'return'.
Cheers
leppie
PS: Continuations confuse the crap out of me. For a beginner I would not worry about it too much, there are much nicer things to learn :)
On Oct 21, 2:32 pm, leppie <xacc....@gmail.com> wrote:
> On Oct 21, 9:53 am, the.brown.dragon.b...@gmail.com wrote:
> > Basically, what's confusing me is line 9 - why is "return" getting > > set! at this point? And how can it be? Won't the continuation jump out > > of the current context so it no longer continues?
> You calling 'return' and not the continuation. Unless you call > 'resume-here', the procedure will always exit, and set! 'return'.
> Cheers
> leppie
> PS: Continuations confuse the crap out of me. For a beginner I would > not worry about it too much, there are much nicer things to learn :)
"return" from (define (control-state return)) _is_ the continuation - or I'm *totally* confused! :-)
> I have just started learning scheme using and got pretty confused when > I reached call-with-current-continuation.
> After reading up on Wikipedia (http://en.wikipedia.org/wiki/Call-with- > current-continuation) I think I've got some idea of how what call/cc > is. But I'm still a bit confused by the example given:
The example is confusing, a little.
Start by rewriting the code so that the lambdas are explicit, and copy propagate the two lambdas to their single use cites:
At point (1), we capture a continuation that, when invokes with a value, will set! return to that value, the continue to the next block. We capture that continuation and set it to control-state and return 1 to the original caller (the top-most return).
If calling (return 1) at the line marked (1) returns a continuation, call it k1, then we have (set! return k1), and control proceeds up to line (2), when the control-state variable is updated with a new continuation, 2 is returned, waiting for a new continuation k2, which updates the "return" variable.
And so on and so forth until you fall off the end.
Stare at it for a while. See if it says something to you. :-)
> > I have just started learning scheme using and got pretty confused when > > I reached call-with-current-continuation.
> > After reading up on Wikipedia (http://en.wikipedia.org/wiki/Call-with- > > current-continuation) I think I've got some idea of how what call/cc > > is. But I'm still a bit confused by the example given:
> The example is confusing, a little.
> Start by rewriting the code so that the lambdas are explicit, > and copy propagate the two lambdas to their single use cites:
> At point (1), we capture a continuation that, when invokes with > a value, will set! return to that value, the continue to the next > block. We capture that continuation and set it to control-state > and return 1 to the original caller (the top-most return).
> If calling (return 1) at the line marked (1) returns a continuation, > call it k1, then we have (set! return k1), and control proceeds up > to line (2), when the control-state variable is updated with a new > continuation, 2 is returned, waiting for a new continuation k2, > which updates the "return" variable.
> And so on and so forth until you fall off the end.
> Stare at it for a while. See if it says something to you. :-)
> Aziz,,,
My head is spinning :)
I'm still not entirely clear - what is wrong with this version?
the.brown.dragon.b...@gmail.com wrote: > I'm still not entirely clear - what is wrong with this version?
It's not wrong. It's just different. The difference happens when you capture and re-invoke a generator, say, after it returns 1 from the sequence (1 2 3). So, you get 1, you "capture" the generator, invoke it and get 2, then you re-invoke the captured generator. Should you get the next element, 3, or should it restart and give you 2? This is the difference.
On Oct 21, 7:48 pm, Abdulaziz Ghuloum <aghul...@cee.ess.indiana.edu> wrote:
> the.brown.dragon.b...@gmail.com wrote: > > I'm still not entirely clear - what is wrong with this version?
> It's not wrong. It's just different. The difference happens when > you capture and re-invoke a generator, say, after it returns 1 from > the sequence (1 2 3). So, you get 1, you "capture" the generator, > invoke it and get 2, then you re-invoke the captured generator. > Should you get the next element, 3, or should it restart and give > you 2? This is the difference.
I think I get what you mean but I'm unable to actually try it out. How would I go about "capturing" the generator?
Does something go wrong here, or is there something wrong in the following exercise? In the exercise, the original version works as I expect, and the new version spins at the first element. See below.
First, I take the code above, and rename the two versions:
> Does something go wrong here, or is there something wrong in the > following exercise? In the exercise, the original version works as I > expect, and the new version spins at the first element. See below.
> First, I take the code above, and rename the two versions:
> Welcome to MzScheme version 202, Copyright (c) 1995-2002 PLT, load all > the code above, and the results are:
> Value of org: (d a r e you-fell-off-the-end you-fell-off-the-end) > Value of new: (d d d d d d)
> All cut-and-pasted as far as possible.
From what I understand of the code, the second version assigns the continuation to "control-state" but does nothing with it. So every call simply starts from the beginning, returning the (expected) first element.
the.brown.dragon.b...@gmail.com writes: > On Oct 21, 11:10 pm, Jussi Piitulainen wrote: > > Abdulaziz Ghuloum writes: > > > The example is confusing, a little.
> > > Start by rewriting the code so that the lambdas are explicit, > > > and copy propagate the two lambdas to their single use cites:
> > Does something go wrong here, or is there something wrong in the > > following exercise? In the exercise, the original version works as I > > expect, and the new version spins at the first element. See below.
> > First, I take the code above, and rename the two versions:
> > Welcome to MzScheme version 202, Copyright (c) 1995-2002 PLT, load all > > the code above, and the results are:
> > Value of org: (d a r e you-fell-off-the-end you-fell-off-the-end) > > Value of new: (d d d d d d)
> > All cut-and-pasted as far as possible.
> From what I understand of the code, the second version assigns the > continuation to "control-state" but does nothing with it. So every > call simply starts from the beginning, returning the (expected) first > element.
Seems so to me, now that I've stared at the code for some time. In the first version, the returned generator passes control-state to call/cc, which then calls it, and during that call it gets re-assigned, so that a different control-state is called next time; in the second version, where is control-state ever called?
I think Abdulaziz meant them to be the same, but when I tried to use them for something, I noticed the difference.
Jussi Piitulainen wrote: > I think Abdulaziz meant them to be the same, but when I tried to use > them for something, I noticed the difference.
Obviously, I completely messed this up. Sorry. Mostly, I was confused by the interface to this generator (e.g., how would one use it). I thought it required a coroutine or something more involved to use it than to simply call it. But now I'm confused for why this needs call/cc at all. Why would one not just do:
> Jussi Piitulainen wrote: > > I think Abdulaziz meant them to be the same, but when I tried to use > > them for something, I noticed the difference.
> Obviously, I completely messed this up. Sorry. Mostly, I was > confused by the interface to this generator (e.g., how would one > use it). I thought it required a coroutine or something more > involved to use it than to simply call it. But now I'm confused > for why this needs call/cc at all. Why would one not just do:
Michele Simionato writes: > You may be interested in this implementation of Python generators > which more or less does what you mean:
Hey, thanks, this is cool. It actually does what I tried to do with that other thing upthread.
> (define-syntax save/cc! > (syntax-rules () > ((_ name body ...) > (call/cc (lambda (cont) (set! name cont) body ...)))))
> (define (generator next) > (define exit #f) > (lambda () > (save/cc! exit ; reassigned the same 'exit' at each iteration > (next (lambda (v) (save/cc! next (exit v)))) > (error 'generator "stop-iteration")); exits here > ))
I modified this so that the "yield" procedure can receive more than one value at each step, the change marked *** below. (I also added an optional "then" to be called after the elements are generated.)
(define generator (case-lambda ; I don't know how standard case-lambda is ((next then) (define exit #f) (lambda () (save/cc! exit ; reassigned the same 'exit' at each iteration (next (lambda vs (save/cc! next (apply exit vs)))) ;*** (then)))); exits here ((next) (generator next (lambda () (error 'generator "stop-iteration"))))))
There are several ways to iterate over combinations of values. I had lying around a procedure (select proc elements) that passes to proc each triple of prefix-element-suffix of elements. I had a procedure (permute proc elements) that passes to proc each permutation of elements, using select. (for-each proc list1 list2) passes proc all pairs of elements in matching positions. Nested for-each calls can pass a proc each pair in the cartesian product of lists.
To illustrate, a simple procedure (threes proc elements) below passes proc each triple of adjacent elements.
Now all such calls can be, it seems, turned into generators.
(define (threes p things) (do ((things things (cdr things)) (n (length things) (- n 1))) ((< n 3)) (p (car things) (cadr things) (caddr things))))
(define g (generator (lambda (yield) (threes yield (string->list "daring")))))
(call-with-values g string) => "dar" (call-with-values g string) => "ari" (call-with-values g string) => "rin" (call-with-values g string) => "ing"
A laboratory case:
(define g (generator (lambda (yield) (yield 'dear 'dare 'read)))) (call-with-values g list) => (dear dare read)
Another:
(define g (generator (lambda (yield) (yield) (yield)))) (call-with-values g string) => "" (call-with-values g string) => ""
> (define g (list->generator '(1 2 3)))
> (list (g) (g) (g)); => (1 2 3)
> (g) ;=> error stop-iteration
> If you don't like the error, you can return a sentinel value to mean > generator termination.
Abdulaziz Ghuloum writes: > Jussi Piitulainen wrote: >> I think Abdulaziz meant them to be the same, but when I tried to >> use them for something, I noticed the difference.
> Obviously, I completely messed this up. Sorry. Mostly, I was
Ok, thanks. No problem.
> But now I'm confused for why this needs call/cc at all. Why would > one not just do:
So it falls flat. But perhaps the for-each call inside the original generate-one-element-at-a-time was struggling to get out, in the way that becomes so much more apparent in Michele Simionato's interesting post. It did what I wanted, at least.
Grant Rettke <gret...@gmail.com> writes: >On Oct 21, 4:32=A0am, leppie <xacc....@gmail.com> wrote: >> PS: Continuations confuse the crap out of me. For a beginner I would >> not worry about it too much, there are much nicer things to learn :) >Leppie, you implemented a R6RS interpreter and still you say this, is >there hope for the rest of us?! :)
Implementing continuations is probably much harder than using them. I know that I am able to use continuations fairly easily if I take a little time to think about the problem.
Aaron Hsu
-- +++++++++++++++ ((lambda (x) (x x)) (lambda (x) (x x))) +++++++++++++++ Email: <arcf...@sacrideo.us> | WWW: <http://www.sacrideo.us> Scheme Programming is subtle; subtlety can be hard. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> I have just started learning scheme using and got pretty confused when > I reached call-with-current-continuation.
> After reading up on Wikipedia (http://en.wikipedia.org/wiki/Call-with- > current-continuation) I think I've got some idea of how what call/cc > is. But I'm still a bit confused by the example given:
> Basically, what's confusing me is line 9 - why is "return" getting > set! at this point? And how can it be? Won't the continuation jump out > of the current context so it no longer continues?
> Help?
> BD
18 (define x (generate-one-element-at-a-time '(1 2 3))) 19 (x)
The set! first evaluates the call/cc call at line 10, and stores the value only after call/cc has returned. But call/cc does not return yet. In line 13 it returns an element to the continuation of the call to x in line 19. So line 19 produces element 1. However, in line 12 variable control-state is updated such as to contain a continuation that finishes the assignment of line 9.
20 (x)
So now the assignment of line 9 is completed. The value is that of (return element) which is the continuation of line 20 as passed to control-state by procedure generator. After the assignment of line 9 is completed, for-each does the next cycle while return points to the continuation of line 20.
> On Oct 21, 4:32 am, leppie <xacc....@gmail.com> wrote: >> PS: Continuations confuse the crap out of me. For a beginner I would >> not worry about it too much, there are much nicer things to learn :)
> Leppie, you implemented a R6RS interpreter and still you say this, is > there hope for the rest of us?! :)
I'd say yes - they are easier to implement than understand.
<findrealaddresswithgoo...@soegaard.net> wrote: > Grant Rettke skrev:
> > On Oct 21, 4:32 am, leppie <xacc....@gmail.com> wrote: > >> PS: Continuations confuse the crap out of me. For a beginner I would > >> not worry about it too much, there are much nicer things to learn :)
> > Leppie, you implemented a R6RS interpreter and still you say this, is > > there hope for the rest of us?! :)
> I'd say yes - they are easier to implement than understand.
I am just now implementing them (full re-invokable continuations), but both implementing and understanding is hard, but I have had some good help from #scheme on freenode.
Hopefully within the next few weeks I will have something working :)
<findrealaddresswithgoo...@soegaard.net> wrote: > Grant Rettke skrev:
> > On Oct 21, 4:32 am, leppie <xacc....@gmail.com> wrote: > >> PS: Continuations confuse the crap out of me. For a beginner I would > >> not worry about it too much, there are much nicer things to learn :)
> > Leppie, you implemented a R6RS interpreter and still you say this, is > > there hope for the rest of us?! :)
> I'd say yes - they are easier to implement than understand.
I am busy implementing them (full re-invokable continuations) for IronScheme at the moment.
Hopefully I will have something working in a few weeks :)
> On Oct 21, 8:53 am, the.brown.dragon.b...@gmail.com wrote:
> > Hello,
> > I have just started learning scheme using and got pretty confused when > > I reached call-with-current-continuation.
> > After reading up on Wikipedia (http://en.wikipedia.org/wiki/Call-with- > > current-continuation) I think I've got some idea of how what call/cc > > is. But I'm still a bit confused by the example given:
> > Basically, what's confusing me is line 9 - why is "return" getting > > set! at this point? And how can it be? Won't the continuation jump out > > of the current context so it no longer continues?
> The set! first evaluates the call/cc call at line 10, and stores the > value only after call/cc has returned. But call/cc does not return > yet. > In line 13 it returns an element to the continuation of the call to x > in line 19. So line 19 produces element 1. > However, in line 12 variable control-state is updated such as to > contain a continuation that finishes the assignment of line 9.
> 20 (x)
> So now the assignment of line 9 is completed. The value is that of > (return element) which is the continuation of line 20 as passed to > control-state by procedure generator. > After the assignment of line 9 is completed, for-each does the next > cycle while return points to the continuation of line 20.
Thanks Jos. I re-read your message 3 times and I think I get it.
So if I understand correctly - a continuation (cont value) returns the next "continuation context". In the example, this is saved in the "return" variable and used in the next iteration.