Sarnold on 2008-05-24: We can have lazy lists in Tcl because we can build new control structures, and here is a package which mimics Python's range() function with Tcl's foreach syntax.
namespace eval ::lazy { namespace export lazy range # constructor proc lazy {initval shift last} { list $initval $shift $last } # gets the first element AND the new list proc _shift {list} { set first [lindex $list 0] lset list 0 [eval [lindex $list 1] [list [lindex $list 0]]] list $first $list } proc shift {listvar} { upvar $listvar list ::foreach {c list} [_shift $list] break set c } # boolean true if the next element (car) is the last # does not modify list proc last {list} { eval [lindex $list 2] [list [lindex $list 0]] } # the new control structure : accepts a lazy list 'list' # otherwise it behaves like foreach except it does not handle # multiple list iterations proc foreach {vars list body} { set res "" while {1} { set last no ::foreach v $vars { if {$last} {return $res} set last [last $list] uplevel 1 [list set $v [shift list]] } set res [uplevel 1 $body] if {$last} {return $res} } } # a range generator proc range {start end {step 1}} { set end [expr {$end - $step}] list $start [list ::lazy::rangeshift $step] [list ::lazy::rangelast $end] } proc rangeshift {step value} { incr value $step } proc rangelast {end value} { expr {$end <=$value} } } # test code namespace import lazy::* foreach step {1 2 3} { set l [range 0 10 $step] lazy::foreach x $l {puts $x} }