Posted to tcl by silas at Thu May 24 23:25:19 GMT 2018view pretty

# Just a coroutine to generate sequential odd numbers
proc next_number {} {
    yield
    set n 10000001
    while {1} {
	yield $n
	incr n 2
    }
}
coroutine next next_number
next

# Check if $n is prime
proc is_prime {n} {
    set max [expr {$n / 2}]
    if {$max % 2 == 0} {
	incr max
    }
    for {set i 3} {$i < $max} {incr i 2} {
	if {$n % $i == 0} {
	    return no
	}
    }
    return yes
}

# Our coroutine.  It "delivers" to [recv]: the number; whether or not it is
# prime; and the coroutine
proc prime {} {
    set n [next]
    while {1} {
	set is_prime [is_prime $n]
	after idle [list recv $n $is_prime [info coro]]
	set n [yield]
    }
}

# Receive coroutine result and call it again with the next number
proc recv {n is_prime caller} {
    if {$is_prime} {
	puts "$caller: $n"
    }
    set n [next]
    $caller $n
}

# Instantiate $maxcoro coroutines
set maxcoro 10
set n 10000001
for {set i 0} {$i < $maxcoro} {incr i} {
    coroutine p($i) prime
    p($i) [next]
}

vwait forever