The case for providing multi-arg'd coroutines is: * coroutines should be able to emulate any command, not just any single-arg'd command [[generality]] * to implement single-arg's coroutines in multi-arg'd coroutines is simple. The converse is inefficient and difficult. [[increase in expressive power]] * there is no sound reason that the invocation of a coroutine should not resemble that of any other command [[principle of minimal surprise]] 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] it is necessary to strip off a single layer of [list]: ====== 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 } ====== <>Enter Category Here