Version 2 of Fibonacci numbers with coroutine

Updated 2015-11-12 09:33:59 by foobar

The following command emits the next Fibonacci number each time it is called.

proc f {} {
    yield [set a 0]
    yield [set b 1]
    while 1 {
        yield [set a [expr {$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 before the first yield to make the first call to fib the zeroth call.

It's about five 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.


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 [set a [expr {$a + $b}]]] eq {}} {
            lassign [list $b $a] a b
        }
    }
}
coroutine fib f

It is only slightly faster than the first command.