coroutine man page on SmartOS

Man page or keyword search:  
man Server   16655 pages
apropos Keyword Search (all sections)
Output format
SmartOS logo
[printable version]

coroutine(n)		     Tcl Built-In Commands		  coroutine(n)


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

       coroutine name command ?arg...?
       yield ?value?
       yieldto command ?arg...?						       │
       name ?value...?							       │

       The  coroutine command creates a new coroutine context (with associated
       command) named name and executes that context by calling command, pass‐
       ing  in	the  other remaining arguments without further interpretation.
       Once command returns normally or with an exception (e.g., an error) the
       coroutine context name is deleted.

       Within  the  context,  values  may be generated as results by using the
       yield command; if no value is supplied, the empty string is used.  When
       that  is	 called,  the context will suspend execution and the coroutine
       command will return the argument to yield. The execution of the context
       can  then be resumed by calling the context command, optionally passing
       in the single value to use as the result of the yield call that	caused
       the  context to be suspended. If the coroutine context never yields and
       instead returns conventionally, the result  of  the  coroutine  command
       will be the result of the evaluation of the context.

       The coroutine may also suspend its execution by use of the yieldto com‐ │
       mand, which instead of  returning,  cedes  execution  to	 some  command │
       called  command (resolved in the context of the coroutine) and to which │
       any number of arguments may be passed. Since every coroutine has a con‐ │
       text command, yieldto can be used to transfer control directly from one │
       coroutine to another (this is only advisable if the two coroutines  are │
       expecting  this	to  happen)  but  any  command may be the target. If a │
       coroutine is suspended by this mechanism, the coroutine processing  can │
       be  resumed  by	calling	 the  context command optionally passing in an │
       arbitrary number of arguments. The return value	of  the	 yieldto  call │
       will  be	 the list of arguments passed to the context command; it is up │
       to the caller to decide what to do with those values.		       │

       The recommended way of writing a version of yield that  allows  resump‐ │
       tion  with  multiple  arguments is by using yieldto and the return com‐ │
       mand, like this:							       │

	      proc yieldm {value} {					       │
		  yieldto return -level 0 $value			       │
	      }								       │

       The coroutine can also be deleted by destroying the command  name,  and
       the name of the current coroutine can be retrieved by using info corou‐
       tine.  If there are deletion traces on  variables  in  the  coroutine's
       implementation,	they  will  fire  at  the  point when the coroutine is
       explicitly deleted (or, naturally, if the command  returns  convention‐

       At  the point when command is called, the current namespace will be the
       global namespace and there will be no stack frames  above  it  (in  the
       sense  of  upvar	 and  uplevel). However, which command to call will be
       determined in the namespace that the coroutine command was called from.

       This example shows a coroutine that will produce an  infinite  sequence
       of even values, and a loop that consumes the first ten of them.

	      proc allNumbers {} {
		  set i 0
		  while 1 {
		      yield $i
		      incr i 2
	      coroutine nextNumber allNumbers
	      for {set i 0} {$i < 10} {incr i} {
		  puts "received [nextNumber]"
	      rename nextNumber {}

       In  this	 example, the coroutine acts to add up the arguments passed to

	      coroutine accumulator apply {{} {
		  set x 0
		  while 1 {
		      incr x [yield $x]
	      for {set i 0} {$i < 10} {incr i} {
		  puts "$i -> [accumulator $i]"

       This example demonstrates the use of coroutines to implement the	 clas‐
       sic Sieve of Eratosthenes algorithm for finding prime numbers. Note the
       creation of coroutines inside a coroutine.

	      proc filterByFactor {source n} {
		  yield [info coroutine]
		  while 1 {
		      set x [$source]
		      if {$x % $n} {
			  yield $x
	      coroutine allNumbers apply {{} {while 1 {yield [incr x]}}}
	      coroutine eratosthenes apply {c {
		  while 1 {
		      set n [$c]
		      yield $n
		      set c [coroutine prime$n filterByFactor $c $n]
	      }} allNumbers
	      for {set i 1} {$i <= 20} {incr i} {
		  puts "prime#$i = [eratosthenes]"

       This example shows how a value can be passed around a  group  of	 three │
       coroutines that yield to each other:				       │

	      proc juggler {name target {value ""}} {			       │
		  if {$value eq ""} {					       │
		      set value [yield [info coroutine]]		       │
		  }							       │
		  while {$value ne ""} {				       │
		      puts "$name : $value"				       │
		      set value [string range $value 0 end-1]		       │
		      lassign [yieldto $target $value] value		       │
		  }							       │
	      }								       │
	      coroutine j1 juggler Larry [				       │
		  coroutine j2 juggler Curly [				       │
		      coroutine j3 juggler Moe j1]] "Nyuck!Nyuck!Nyuck!"       │

       This  example demonstrates that coroutines start from the global names‐
       pace, and that command resolution happens before the coroutine stack is

	      proc report {where level} {
		  # Where was the caller called from?
		  set ns [uplevel 2 {namespace current}]
		  yield "made $where $level context=$ns name=[info coroutine]"
	      proc example {} {
		  report outer [info level]
	      namespace eval demo {
		  proc example {} {
		      report inner [info level]
		  proc makeExample {} {
		      puts "making from [info level]"
		      puts [coroutine coroEg example]

       Which  produces	the output below. In particular, we can see that stack
       manipulation has occurred (comparing the levels from the first and sec‐
       ond  line)  and	that  the  parent level in the coroutine is the global
       namespace. We can also see that coroutine names are local to  the  cur‐
       rent namespace if not qualified, and that coroutines may yield at depth
       (e.g., in called procedures).

	      making from 2
	      made inner 1 context=:: name=::demo::coroEg

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

       coroutine, generator

Tcl				      8.6			  coroutine(n)

List of man pages available for SmartOS

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
Vote for polarhome
Free Shell Accounts :: the biggest list on the net