1coroutine(n) Tcl Built-In Commands coroutine(n)
2
3
4
5______________________________________________________________________________
6
8 coroutine, yield, yieldto - Create and produce values from coroutines
9
11 coroutine name command ?arg...?
12 yield ?value?
13 yieldto command ?arg...? │
14 name ?value...? │
15______________________________________________________________________________
16
18 The coroutine command creates a new coroutine context (with associated
19 command) named name and executes that context by calling command, pass‐
20 ing in the other remaining arguments without further interpretation.
21 Once command returns normally or with an exception (e.g., an error) the
22 coroutine context name is deleted.
23
24 Within the context, values may be generated as results by using the
25 yield command; if no value is supplied, the empty string is used. When
26 that is called, the context will suspend execution and the coroutine
27 command will return the argument to yield. The execution of the context
28 can then be resumed by calling the context command, optionally passing
29 in the single value to use as the result of the yield call that caused
30 the context to be suspended. If the coroutine context never yields and
31 instead returns conventionally, the result of the coroutine command
32 will be the result of the evaluation of the context.
33
34 The coroutine may also suspend its execution by use of the yieldto com‐ │
35 mand, which instead of returning, cedes execution to some command │
36 called command (resolved in the context of the coroutine) and to which │
37 any number of arguments may be passed. Since every coroutine has a con‐ │
38 text command, yieldto can be used to transfer control directly from one │
39 coroutine to another (this is only advisable if the two coroutines are │
40 expecting this to happen) but any command may be the target. If a │
41 coroutine is suspended by this mechanism, the coroutine processing can │
42 be resumed by calling the context command optionally passing in an ar‐ │
43 bitrary number of arguments. The return value of the yieldto call will │
44 be the list of arguments passed to the context command; it is up to the │
45 caller to decide what to do with those values. │
46
47 The recommended way of writing a version of yield that allows resump‐ │
48 tion with multiple arguments is by using yieldto and the return com‐ │
49 mand, like this: │
50
51 proc yieldm {value} { │
52 yieldto return -level 0 $value │
53 } │
54
55 The coroutine can also be deleted by destroying the command name, and
56 the name of the current coroutine can be retrieved by using info corou‐
57 tine. If there are deletion traces on variables in the coroutine's im‐
58 plementation, they will fire at the point when the coroutine is explic‐
59 itly deleted (or, naturally, if the command returns conventionally).
60
61 At the point when command is called, the current namespace will be the
62 global namespace and there will be no stack frames above it (in the
63 sense of upvar and uplevel). However, which command to call will be de‐
64 termined in the namespace that the coroutine command was called from.
65
67 This example shows a coroutine that will produce an infinite sequence
68 of even values, and a loop that consumes the first ten of them.
69
70 proc allNumbers {} {
71 yield
72 set i 0
73 while 1 {
74 yield $i
75 incr i 2
76 }
77 }
78 coroutine nextNumber allNumbers
79 for {set i 0} {$i < 10} {incr i} {
80 puts "received [nextNumber]"
81 }
82 rename nextNumber {}
83
84 In this example, the coroutine acts to add up the arguments passed to
85 it.
86
87 coroutine accumulator apply {{} {
88 set x 0
89 while 1 {
90 incr x [yield $x]
91 }
92 }}
93 for {set i 0} {$i < 10} {incr i} {
94 puts "$i -> [accumulator $i]"
95 }
96
97 This example demonstrates the use of coroutines to implement the clas‐
98 sic Sieve of Eratosthenes algorithm for finding prime numbers. Note the
99 creation of coroutines inside a coroutine.
100
101 proc filterByFactor {source n} {
102 yield [info coroutine]
103 while 1 {
104 set x [$source]
105 if {$x % $n} {
106 yield $x
107 }
108 }
109 }
110 coroutine allNumbers apply {{} {while 1 {yield [incr x]}}}
111 coroutine eratosthenes apply {c {
112 yield
113 while 1 {
114 set n [$c]
115 yield $n
116 set c [coroutine prime$n filterByFactor $c $n]
117 }
118 }} allNumbers
119 for {set i 1} {$i <= 20} {incr i} {
120 puts "prime#$i = [eratosthenes]"
121 }
122
123 This example shows how a value can be passed around a group of three │
124 coroutines that yield to each other: │
125
126 proc juggler {name target {value ""}} { │
127 if {$value eq ""} { │
128 set value [yield [info coroutine]] │
129 } │
130 while {$value ne ""} { │
131 puts "$name : $value" │
132 set value [string range $value 0 end-1] │
133 lassign [yieldto $target $value] value │
134 } │
135 } │
136 coroutine j1 juggler Larry [ │
137 coroutine j2 juggler Curly [ │
138 coroutine j3 juggler Moe j1]] "Nyuck!Nyuck!Nyuck!" │
139
140 DETAILED SEMANTICS
141 This example demonstrates that coroutines start from the global name‐
142 space, and that command resolution happens before the coroutine stack
143 is created.
144
145 proc report {where level} {
146 # Where was the caller called from?
147 set ns [uplevel 2 {namespace current}]
148 yield "made $where $level context=$ns name=[info coroutine]"
149 }
150 proc example {} {
151 report outer [info level]
152 }
153 namespace eval demo {
154 proc example {} {
155 report inner [info level]
156 }
157 proc makeExample {} {
158 puts "making from [info level]"
159 puts [coroutine coroEg example]
160 }
161 makeExample
162 }
163
164 Which produces the output below. In particular, we can see that stack
165 manipulation has occurred (comparing the levels from the first and sec‐
166 ond line) and that the parent level in the coroutine is the global
167 namespace. We can also see that coroutine names are local to the cur‐
168 rent namespace if not qualified, and that coroutines may yield at depth
169 (e.g., in called procedures).
170
171 making from 2
172 made inner 1 context=:: name=::demo::coroEg
173
175 apply(n), info(n), proc(n), return(n)
176
178 coroutine, generator
179
180
181
182Tcl 8.6 coroutine(n)