From: Neil M. <nem@Cs.Nott.AC.UK> - 2010-04-15 07:34:51
|
You don't need all that complication to implement multi-arg coros. Just apply some curry as needed: proc curry {cmd args} { $cmd $args } Then when you need your coro to accept multiple args: do_something [list curry $coro] Neil On 15 Apr 2010, at 05:04, Colin McCormack <co...@ch...> wrote: > I wish to consider amending "TIP 328 Coroutines" > http://www.tcl.tk/cgi-bin/tct/tip/328.html, along these lines: > > Invocation of a coroutine should accept multiple arguments, those > arguments should be returned to the coroutine's ::yield as a list of > actual parameters. > > The current implementation forbids invoking a coroutine with more than > one argument. I have found, in practice, that many of my coroutine > invocations are naturally like other command invocations, and take > multiple arguments. > > The case for providing multi-arg'd coroutines is: > > 1. coroutines should be able to emulate any command, not just any > single-arg'd command [generality] > 2. to implement single-arg's coroutines in multi-arg'd coroutines is > simple. The converse is inefficient and difficult. [increase in > expressive power] > 3. there is no sound reason that the invocation of a coroutine > should > not resemble that of any other command [principle of minimal > surprise] > > For this reason, the core should be modified to accept multiple actual > parameters to a coroutine invocation, ::yield should be modified to > resemble ::yield2 below, and a new interface ::yieldm should be > created > to return the actual parameter list as it's passed. > > Demonstration of point 2 > > CASE 1: (counterfactual) > Assume a Coroutine which generates a command taking multiple args, to > implement coroutine as we have it implemented: > > proc coroutine {name command args} { > set ns [namespace qualifiers $name] > if {$ns eq ""} { > set ns [uplevel 1 {namespace current}] > } > set name [namespace tail $name] > > Coroutine ${ns}::$name $command {*}$args > } > > To provide precisely the same functionality as yield > <http://wiki.tcl.tk/13849> it is necessary to strip off a single layer > of list <http://wiki.tcl.tk/440>: > > proc ::yield2 {value} { > return [lindex [::yield $value] 0] > } > > No other changes are necessary. More likely, one would define ::yield > like that, and create a new ::yield-variant which returned the whole > invocation arg list. > > CASE 2: Coroutine in coroutine - implementing multi-arg'd coroutines > over singe-arg'd coroutine. > > proc Coroutine {name command args} { > set ns [namespace qualifiers $name] > if {$ns eq ""} { > set ns [uplevel 1 {namespace current}] > } > set name [namespace tail $name] > > set coco [::coroutine ${ns}::_C$name $command {*}args] > trace add command ${ns}::_C$name delete "rename ${ns}::name {}" > proc ${ns}::$name {args} { > set name [lindex [info level 0] 0] > set ns [namespace qualifiers $name] > if {$ns eq ""} { > set ns [uplevel 1 {namespace current}] > } > set name [namespace tail $name] > > ${ns}::_C$name $args > } > } > > Counterfactual side-benefits: ::yield stays exactly as it is.Yield to > populate args becomes simpler. > > proc yieldv {value args} { > uplevel 1 [::yield $value] {*}$args > } > > > > --- > --- > --- > --------------------------------------------------------------------- > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > _______________________________________________ > Tcl-Core mailing list > Tcl...@li... > https://lists.sourceforge.net/lists/listinfo/tcl-core |