The following command emits one of the [Fibonacci numbers], the next in the series, each time it is called. ====== proc f {} { yield [set a 0] yield [set b 1] while 1 { yield [incr a $b] lassign [list $b $a] a b } } coroutine fib f ====== The call to `[coroutine]` is considered to be fib(0) and returns 0. Add a nullary `[yield]` (or the customary `yield [[[info coroutine]]]`) before the first `yield` to make the first call to `fib` the zeroth call. It's about six times slower than `::math::fibonacci`, but it's hard to compare timing when the coroutine needs to be destroyed and reinstated during every iteration, and the call to `fib` wrapped in a `[for]` statement to advance the sequence. Time by: ====== time {for {set i 0} {$i <= 46} {incr i} fib ; rename fib "" ; coroutine fib f} 100000 ;# relative 5.5 time {::math::fibonacci 46} 100000 ;# relative 1.0 ====== ---- This command allows the Fibonacci series to be restarted if an argument is passed to `fib`: ====== proc f {} { yield while 1 { yield [set a 0] yield [set b 1] while {[yield [incr a $b]] eq {}} { lassign [list $b $a] a b } } } coroutine fib f ====== It is only slightly faster than the first command. Using this code and calling `fib` 46 times instead of using a loop makes this implementation about three times slower than `::math::fibonacci`. Time by: ====== time {for {set i 0} {$i <= 46} {incr i} fib ; fib stop} 100000 ;# relative 4.9 time { fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib fib ; fib ; fib ; fib ; fib ; fib fib reset } 100000 ;# relative 3.1 ====== <>Mathematics