From: Donal K. Fellows on 6 Feb 2010 16:23 On 05/02/2010 17:02, Paul wrote: > The crucial point is that I want to be able to run commands contained > in a Tcl procedure from my C code. Then be able to stop, and run > commands in a different Tcl procedure. Then later on carry on > executing commands in the first procedure. I'm hoping that the Tcl C > API will support this. Conceptually it sounds simple, but in reality > it might be more difficult. That's definitely coroutines. (Yes, the reality of implementation has indeed proved to be quite difficult, but we're now through that.) They allow you to create a command, a coroutine, that works by executing until a yield point when it stops. You can then call that coroutine again to allow it to resume from where it stopped. You can do this as much as you want. (You can hide the yield inside other procedures if you want; Tcl 8.6 does all the stack management to make that Just Work™ the way you'd hope for.) Before you ask, there's no hope at all of backporting this feature to any previous version of Tcl. I've heard of things being hacked together with threads that behave similarly, but there's no way I can recommend that level of lash-together... Donal.
From: Paul on 7 Feb 2010 12:35 On Feb 6, 4:23 pm, "Donal K. Fellows" <donal.k.fell...(a)manchester.ac.uk> wrote: > That's definitely coroutines. (Yes, the reality of implementation has > indeed proved to be quite difficult, but we're now through that.) They > allow you to create a command, a coroutine, that works by executing > until a yield point when it stops. You can then call that coroutine > again to allow it to resume from where it stopped. You can do this as > much as you want. (You can hide the yield inside other procedures if you > want; Tcl 8.6 does all the stack management to make that Just Work the > way you'd hope for.) > > Before you ask, there's no hope at all of backporting this feature to > any previous version of Tcl. I've heard of things being hacked together > with threads that behave similarly, but there's no way I can recommend > that level of lash-together... > > Donal. OK - thanks. I'm having a look at coroutines, and in particular TIP 328, and I can't understand the section "New commands and Subcommands", and so I have some questions. Using the example below: proc aProc {} { puts 1 yield puts 2 yield puts 3 } proc cr {} { aProc aProc } coroutine cr aProc I understand that the coroutine command will run aProc. The yield in aProc suspends execution in aProc. TIP 328 explains that a yield in the coroutine with create a commanmd with special behaviour. It's not clear to me what the significance of the created command is or what I have to do with it. I'm guessing I need to to specify a proc with the same name, as above? TIP 328 then says the coroutine returns to the caller not the creater. What is the caller and what is the creater? Again, guessing, the creater is the coroutine command call, and the caller the subsequent calls to the coroutine? The TIP then explains that coroCmdName resumes execution of the coroutine (cr in this case), etc... That paragraph is as clear as mud to me I'm afraid :-) Coroutines 101! At the moment I'd like to get the above to the stage so that it prints out 1, 2, 3. Regards, Paul.
From: miguel sofer on 7 Feb 2010 12:46 Paul wrote: > On Feb 6, 4:23 pm, "Donal K. Fellows" > <donal.k.fell...(a)manchester.ac.uk> wrote: > >> That's definitely coroutines. (Yes, the reality of implementation has >> indeed proved to be quite difficult, but we're now through that.) They >> allow you to create a command, a coroutine, that works by executing >> until a yield point when it stops. You can then call that coroutine >> again to allow it to resume from where it stopped. You can do this as >> much as you want. (You can hide the yield inside other procedures if you >> want; Tcl 8.6 does all the stack management to make that Just Work� the >> way you'd hope for.) >> >> Before you ask, there's no hope at all of backporting this feature to >> any previous version of Tcl. I've heard of things being hacked together >> with threads that behave similarly, but there's no way I can recommend >> that level of lash-together... >> >> Donal. > > OK - thanks. > > I'm having a look at coroutines, and in particular TIP 328, and I > can't understand the section "New commands and Subcommands", and so I > have some questions. Using the example below: > > > proc aProc {} { > puts 1 > yield > puts 2 > yield > puts 3 > } > > proc cr {} { > aProc > aProc > } > > coroutine cr aProc > > > I understand that the coroutine command will run aProc. The yield in > aProc suspends execution in aProc. > > TIP 328 explains that a yield in the coroutine with create a commanmd > with special behaviour. It's not clear to me what the significance of > the created command is or what I have to do with it. I'm guessing I > need to to specify a proc with the same name, as above? > > TIP 328 then says the coroutine returns to the caller not the creater. > What is the caller and what is the creater? Again, guessing, the > creater is the coroutine command call, and the caller the subsequent > calls to the coroutine? > > The TIP then explains that coroCmdName resumes execution of the > coroutine (cr in this case), etc... That paragraph is as clear as mud > to me I'm afraid :-) > > Coroutines 101! At the moment I'd like to get the above to the stage > so that it prints out 1, 2, 3. % proc aProc {} { puts 1 yield puts 2 yield puts 3 } % proc cr {} aProc % coroutine foo cr; #1 1 % foo; #2 2 % foo 3 % foo invalid command name "foo" #1 creates the command 'foo' that will reawaken the coroutine, then runs the command 'cr' until it yields. Subsequent calls to 'foo' (#2 et al) restart the coroutine until the next 'yield'. The command 'foo' is deleted when the coroutine returns (as opposed to yielding). HTH Miguel
From: Paul on 7 Feb 2010 13:05
On Feb 7, 5:46 pm, miguel sofer <mso...(a)users.sf.net> wrote: > % proc aProc {} { > puts 1 > yield > puts 2 > yield > puts 3} > > % proc cr {} aProc > % coroutine foo cr; #1 > 1 > % foo; #2 > 2 > % foo > 3 > % foo > invalid command name "foo" > > #1 creates the command 'foo' that will reawaken the coroutine, then runs > the command 'cr' until it yields. > > Subsequent calls to 'foo' (#2 et al) restart the coroutine until the > next 'yield'. The command 'foo' is deleted when the coroutine returns > (as opposed to yielding). > > HTH > Miguel OK, I now understand. Thanks, Paul. |