1coroutine(n)                 Tcl Built-In Commands                coroutine(n)
2
3
4
5______________________________________________________________________________
6

NAME

8       coroutine, yield, yieldto - Create and produce values from coroutines
9

SYNOPSIS

11       coroutine name command ?arg...?
12       yield ?value?
13       yieldto command ?arg...?                                                │
14       name ?value...?                                                         │
15______________________________________________________________________________
16

DESCRIPTION

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

EXAMPLES

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

SEE ALSO

175       apply(n), info(n), proc(n), return(n)
176

KEYWORDS

178       coroutine, generator
179
180
181
182Tcl                                   8.6                         coroutine(n)
Impressum