====== # returns an unused procedure name proc gensym {prefix} { tailcall apply {{prefix} { string cat $prefix[llength [info commands $prefix*]] }} $prefix } # creates an anonymous coroutine. New features: # . avoid poluting the global namespace # . return a FQ command name, usable in any context namespace eval ::goro {} proc go {cmd args} { set name [gensym ::goro::#] coroutine $name $cmd {*}$args return $name } ====== Credit for the above code goes to [aspect]. The odd construct with `tailcall apply` is so that [info commands] will be executed in the caller's namespace. [MS] finds that this construct has a big problem: name reuse. Some code could be holding onto a coro handle, and wanting to find out if it still exists via [[info command]] (or just waiting to error out, intentionally or not). If the coro exited and a new one was created with the same name, chaos could ensue ... So my proposal is to either use a global counter (possibly in a namespace). If we really cannot live with a global var, we could do: ====== coroutine gensym apply {{} { set prefix [yield] while 1 { set name $prefix[dict incr counters $prefix] if {[llength [uplevel 1 [list info commands $name]]]} continue set prefix [yield $name] } }} ====== [aspect]: great observation! I've previously used a [[gensym]] like the above, but switched to the "less stateful" one above for exploring CSP. The risk of hard-to-diagnose errors is a Very Good Reason to avoid name reuse. [MS] modified [[gensym]] to take care ef emiliano's observation in the chat: we should verify that the command does not already exist. <>Concurrency