Variables declared within the main body of a coroutine persist for the life of the coroutine. This much is obvious. What may be less obvious is that you can access those variables from commands called from the coro, using [upvar #1], so here's a little wrapper to facilitate that:

    proc corovars {args} {
        foreach n $args {lappend v $n $n}
        uplevel 1 [list upvar #1 {*}$v]

So, coro-persistent variables may be declared thus within procs:

    corovars x y z

MS a variant that builds the list in a more direct manner is

    proc corovars {args} {
        set cmd [list upvar #1]
        foreach n $args {lappend cmd $n $n}
        uplevel 1 $cmd

AMG: I use this trick in Wibble; it's very helpful. See [::wibble::cleanup] in Wibble implementation. See WebSocket for more examples of use.