Version 17 of yieldTo

Updated 2014-09-25 13:32:57 by APN

Command in Tcl 8.6:

yieldto command ?arg …?

Suspends the current coroutine and makes the current coroutine's caller invoke command (with the optional args). Command is resolved prior the suspension in the context of the current coroutine, and can refer to another coroutine (though this is not required). May only be called from within a coroutine; it is an error to call it from elsewhere.

Exceptions:

TCL COROUTINE ILLEGAL_YIELD — if called from an illegal context (i.e., not in a coroutine).
TCL COROUTINE CANT_YIELD — there is a coroutine context, but a non-NRE-aware C command is gumming up the works.

When resumed, returns the list of arguments passed to the coroutine's resumption command. (This is different to yield, which makes the resumption command take a single optional argument that defaults to the empty string.)

[This wiki page has a capital letter in its name for historical reasons.]


 

The following conversation with MS was very enlightening for me. So preserving for posterity.

[18:55]        apn        miguel, the inject worked fine
[18:56]        apn        You can even do multiple injects though the injected code cannot inject itself for the next call (only tried it to see what would happen)
[18:59]        miguel        apn: by design you can only inject code into a sleeping coro ... head hurts imagining how to insure the alternative works properly
[19:01]        apn        miguel, reasonable. I was trying it only to see what would happen. Not surprised it raised an error
[19:03]        miguel        note that you could build something like that using [yieldto] - which is quite explicit as to when things happen
[19:04]        miguel        ... so, if you really need it, you can easily build an [autoinject] out of [yieldto], [info coroutine] and [inject]
[19:07]        apn        I have not progressed to yieldto yet or have a use case for it that is obvious (to me)
[19:07]        miguel        well, autoinject would be a use case 
[19:08]           * jima neither has "visualized" yieldto
[19:08]        miguel        yieldto is to yield as tailcall is to return
[19:08]        apn        Kind of get that, but not quite where it might be used
[19:08]        apn        other than autoinject 
[19:10]        miguel        if you want to "yield" with a non-OK code, you can do eg 'yieldto return -code continue'
[19:10]        miguel        ... the coro yields, but the coro's caller sees a continue return
[19:12]        apn        So for example if I want to return a -break from a Tk bind callback script that invoked a coro ?
[19:13]        miguel        (more examples abound, symmetric coroutines among them)
[19:13]        apn        I was actually wondering about that this afternoon experimenting with integrating Tk with a coro based fiber package I wrote
[19:14]           * miguel answers a generic "yes", without actually being sure about what the question was
[19:15]        apn        Something like
[19:15]        apn        bind MyTkTag <<MyEvent>> "do something; break"
[19:15]        apn        If instead, I was to call a coro like
[19:16]        apn        bind MyTkTag <<MyEvent>> "mycoro %W"
[19:16]        apn        and wanted mycoro to return a break
[19:16]        apn        so further bound scripts would not get execututed
[19:16]        apn        whatever execututed means
[19:17]        apn        If mycoro was a normal proc, it could do a [return -code break]
[19:17]        miguel        ok - if the coro should go to sleep (yield), then it should the above trick of yieldto'ing to [break]
[19:18]        miguel        ... if it should die after doing its stuff, [return -code break] is a possibility (with the appropriate -level if it is returning from some nested proc call)
[19:19]        apn        I was thinking of the first case
[19:20]        miguel        [yieldto break] should do it ... or [yieldto return -code break]
19:25]        miguel        apn: [yieldto] yields to another command, it doesn't have to be another coro. It just means 'put the present coro to sleep, remove it from Tcl's and C call stacks, and run this other command in it's place (without the coro's caller ever nticing a thing)'
[19:26]        miguel        ... some kind of delegation - let my minion do the job, it's siesta time for me
[19:26]        apn        So what this other command returns is what the original caller of the coro sees ? Cool!
[19:27]        apn        (as the return value I mean)
[19:27]        miguel        yup ... that's the tailcall-like aspect
[19:27]        apn        *now* I get it

Prehistory

New experimental command added in ::tcl::unsupported on 2009-12-07.

tcl::unsupported::yieldTo command ?arg ...?

Suspends the current coroutine and makes the current coroutine's caller invoke command (with the optional args). Command is resolved prior the suspension in the context of the current coroutine, and can refer to another coroutine (though this is not required). May only be called from within a coroutine; it is an error to call it from elsewhere.

Exceptions:

TCL COROUTINE ILLEGAL_YIELD — if called from an illegal context (i.e., not in a coroutine).

Docs forthcoming, for now just the tclcore thread at [L1 ]


AMG: Why is this command named with an internal capital letter? All other built-in Tcl commands (as opposed to utility procs) are named with multiple words (or abbreviations thereof) jammed together with no capitals or underscores. Examples abound: [bgerror], [fblocked], [foreach], [gets], [lappend], [regexp], [uplevel], and [vwait].

MS no special reason

CRC From the thread, it appears that the author of this code just likes, or is used to, camel case. In the ensuing discussion it was referred to as "yieldto". Not being a fan of camel case myself, I hope that if it gets incorporated, it is "yieldto", or "yield -target" as DKF suggests.

DGP FWIW, there are precedents in the other direction as well: pkg_mkIndex, tcl_findLibrary, tcl_endOfWord, etc.

AMG: Those are the utility procs I was referring to.


jbr - I'm wondering why we are polluting the global namespace with yield variants. Don't people already have complaints about the many list commands and the file io commands not being grouped together?

AMG: Same question. Some time ago there was a discussion on tcl-core regarding [yield], [yieldTo], and [yieldm]. I don't recall how it was resolved, or even if it was resolved at all. I advocated unifying these three commands into a single [yield] command that takes options. In addition to cleaning up the global namespace, this would close the gap between [yieldTo] and [yieldm]: how do you instruct the current coroutine's caller to invoke a command, while making the current coroutine's resume command accept any number of arguments?