This proc is a useful little tool for parsing options to a command. iter acts exactly like a foreach loop, but exposes the [next] command inside the body of the loop, which jumps the iterating variable to the next value in the list and returns that value. proc iter { var list body } { coroutine next apply [subst {{} { yield foreach x {$list} { yield \$x } return -code break }}] while 1 { uplevel [list set $var [next]] uplevel $body } } Here is an example. Say we want to write a command, scrape, which pulls down webpages. scrape has a '-o' option which takes a filename to write the data to, and a '-ssl' option that enables ssl in the http request. A scrape call that pulls down www.foo.com/index.html might look like this scrape www.foo.com/index.html -o foo.html -ssl Here's how we can use iter to parse the options to scrape proc scrape { addr args } { set outfile [lindex [split $addr /] end] set usessl 0 iter op $args { switch $op { -o { set outfile [next] } -ssl { set usessl 1 } } } # do scraping here } When the '-o' option is seen, the variable 'outfile' is set to the [next] element in the list, which is the filename passed after -o. In our case 'foo.html'. When that iteration finishes, and iter gets to the top of its loop, it will assign the variable after 'foo.html' to op. In our case this is '-ssl', which will be matched and the variable usessl will be set to 1. Theoretically you can nest loops that keep [next]ing, but I haven't tried that yet. -- About a month later... -- Looking over this code now, I think I see how it can be abstracted another level. We can bundle the call to [iter] and [switch] inside a command, [argparse]. Then we can write the above like this. argparse $args { -o { set outfile [next] } -ssl { set usessl 1 } } Nice. So what does the argparse command look like? proc argparse { options switch_body } { uplevel [subst {iter op $options { switch \$op { $switch_body } }}] } And now we write scrape with the new abstraction proc scrape { addr args } { set outfile [lindex [split $addr /] end] set usessl 0 argparse $args { -o { set outfile [next] } -ssl { set usessl 1 } } # do scraping here }