This is a drop-in replacement for the standard [for] command. It supports an expanded syntax for looping over [iterator protocol%|%iterators]. It can be downloaded as a part of [ycl]. **usage** ======none for {varname1 ...} in iterator_name1 [{varname {varnameX ... } in iterator_nameX] ... script ====== **description** like [foreach] does with list, it can operate on multiple iterators and take an arbitrary number of items each time from each iterator. Also like [foreach], empty strings are produced as necessary for any iterator which becomes depleted before the others. note that [return -code break] within an iterator will cause the main [for] loop to break, so it should be used with care. **Code** newer code may be available in the [ycl] repository ====== rename ::for for_core interp alias {} ::for {} [namespace current]::for proc for args { if {[lindex $args 1] eq "in"} { if {[llength $args] % 3 != 1} { return -code error "wrong number of arguments for [info level 0]" } set assigns {} set assign_template { if {[namespace which $iter] eq {}} { variable $varname {} } else { variable $varname [$iter] } } set conditions {} set condition_template {[namespace which $iter] ne {}} while {[llength $args] > 1} { set args [lassign $args[unset args] varnames {} iter] foreach varname $varnames { lappend assigns [string map [list \$iter [list $iter] \$varname [list $varname]] \ $assign_template] } lappend conditions [string map [list \$iter [list $iter]] $condition_template] } set assigns [join $assigns \n] set args [join $args \n] uplevel "while {[join $conditions { || }]} {$assigns\n$args}" } else { uplevel [list [namespace current]::for_core {*}$args] } } ====== example ====== set result [list] for {key val} in [coroutine students apply {{} { yield [info coroutine] set db { Jack 97 Sally 89 Bob 83 Jill 77 John 72 } set index -1 foreach {name score} $db { yield $name yield $score } return -code break }}] prize in [coroutine prizes apply {{} { yield [info coroutine] foreach item { first second third } { yield $item } }}] { lappend result $key $val $prize } puts $result ====== produces: ======none Jack 97 first Sally 89 second Bob 83 third Jill 77 {} John 72 {} ====== <> Category Control Structure