[SS]: Python's alike range. The semantic should be exactly the same (and seems the more sensible for Tcl also). Examples: range 10 ;# => 0 1 2 3 4 5 6 7 8 9 range 10 20 ;# => 10 11 12 13 14 15 16 17 18 19 range 10 20 2 ;# => 10 12 14 16 18 range 20 10 -2 ;# => 20 18 16 14 12 Code: # range ?start? end ?step? # # Python's alike range function. # Returns the [start,end) integer range. # # Example: # # foreach x [range 0 10] y [range 20 0 -2] { # puts "$x $y" # } proc range args { set l [llength $args] if {$l == 1} { set start 0 set step 1 set end [lindex $args 0] } elseif {$l == 2} { set step 1 foreach {start end} $args break } elseif {$l == 3} { foreach {start end step} $args break } else { error {wrong # of args: should be "range ?start? end ?step?"} } set result {} if {$start <= $end} { for {set j $start} {$j < $end} {incr j $step} { lappend result $j } } else { for {set j $start} {$j > $end} {incr j $step} { lappend result $j } } return $result } I think the Tcl core should include the [range] command as proposed in my reference implementation (that's semantically equivalent to Python's) for the following reasons: * Sequences of natural numbers are often useful in programming, so the command is of very general use. * It may become idiomatic to write: foreach x [range 0 10] instead of for {set x 0} {$x < 10} {incr x} for small loops. It's much clear. * The Python semantic appears to be the best for languages where indexes are zero-based (Pascal noted it, and I think it's a smart observation). * If implemented in a smart way, [range] may speed-up Tcl loops comprated to [for]. A smart implementation should cache small ranges and return the shared object for the next call. * At some point Tcl may include TIP 192 in order to make ranges used for loops to have a space complexity of O(1). ---- [RS]: Here's a minimal variant that only does step-width 1: proc range {from to} { if {$to>$from} {concat [range $from [incr to -1]] $to} } % range 0 5 0 1 2 3 4 % range 1 6 1 2 3 4 5 [DKF]: Extending is easy. proc range {from to {step 1}} { if {$to>$from} {concat $from [range [incr from $step] $to $step]} } however this is inefficient. Better to do this: proc range {from to {step 1}} { set res $from; while {$to>$from} {lappend res [incr from $step]}; return $res } or even this, adapting to work with negative steps... proc range {from to {step 1}} { set res $from while {$step>0?$to>$from:$to<$from} {lappend res [incr from $step]} return $res } ---- See also [Integer range generator] ---- [Category Algorithm]