if 0 {[Richard Suchenwirth] 2004-01-25 - For counted loops, Tcl has inherited the [for] command from C with its lengthy syntax. [Python] on the other hand provides only a list iterator like Tcl's [foreach], and offers an integer range constructor range() to iterate over counted loops: range(1,5) -> [1, 2, 3, 4] range(4) -> [0, 1, 2, 3] (A similar thing was the index vector generator, iota, in APL). You can also specify the step-width, which might also be negative. This construct comes handy in Tcl too, where we can then choose between for {set i 0} {$i < 5} {incr i} {...} foreach i [.. 0 5] {...} I chose the fancy name ".." as suggestive for a range. Here's the code:} proc .. {a {b ""} {step 1}} { if {$b eq ""} {set b $a; set a 0} ;# argument shift if {![string is int $a] || ![string is int $b]} { scan $a %c a; scan $b %c b incr b $step ;# let character ranges include the last set mode %c } else {set mode %d} set ss [sgn $step] if {[sgn [expr {$b - $a}]] == $ss} { set res [format $mode $a] while {[sgn [expr {$b-$step-$a}]] == $ss} { lappend res [format $mode [incr a $step]] } set res } ;# one-armed if: else return empty list } proc sgn x {expr {$x>0? 1: $x<0? -1: 0}} if 0 {For testing this, I came up with a cute and tiny asserter/tester routine:} proc must {cmd result} { if {[set r [uplevel 1 $cmd]] != $result} { error "$cmd -> $r, expected $result" } } #-- Tests pass silently, but raise an error if expectations are not met: must {.. 5} {0 1 2 3 4} must {.. 0 10 3} {0 3 6 9} must {.. -10 -100 -30} {-10 -40 -70} must {.. 2 -2 -1} {2 1 0 -1} must {.. 0 0} {} must {.. A D} {A B C D} must {.. z a -1} {z y x w v u t s r q p o n m l k j i h g f e d c b a} ---- [RWT] That's nice, but don't forget that all the power of [tcltest] is always at your fingertips. And test suites are quite easy. Just like you wrote, but add a test name and description to each one. package require tcltest namespace import ::tcltest::* test range-1.0 {zero to int} {.. 5} {0 1 2 3 4} test range-1.1 {specify increment} {.. 0 10 3} {0 3 6 9} test range-1.2 {negatives} {.. -10 -100 -30} {-10 -40 -70} test range-1.3 {negative increment} {.. 2 -2 -1} {2 1 0 -1} test range-1.4 {zeros} {.. 0 0} {} test range-2.0 {cap letters} {.. A D} {A B C D} test range-2.1 {lowercase, backwards} {.. z a -1} {z y x w v u t s r q p o n m l k j i h g f e d c b a} [RS] Hm... On the [iPaq], where I test much, I don't have tcltest. And in place of a large thing where the synopsis in the 630-line man page lists just 40 ways of calling, I prefer a 5-liner which I can configure as I wish (e.g. add timing) - and have one dependency less :) Nothing against Tcltest, but I usually prefer the simplest thing that works. ---- [KPV] It would be useful if this function also had the ability to generate alphabet ranges, e.g [[.. A D]] => {A B C D}. [Perl] has this capability and it's surprisingly useful. - [RS]: Your wish is my command :) It didn't take much to change, considering that characters ''are'' integers. For convenience I allowed (as your example suggests) that character ranges run up to the last specified character (while for integers, they run until just below the end limit...) [SS] A direct extension is to consider ranges between two words, for example [.. z ac 1] => z aa ab. This makes it much more useful, for example you can use it to search a password with brute-force. I don't like the command name .., since there is one very good, descriptive and short: [range]. Also with the extension I proposed, the command needs an option or to be split in two commands, since e.g. 1 99 is also a valid alphabetical range. - [RS]: Regarding .., of course you can name it as you wish - I just made that up in fleeting fancy (and to show off that we can have more names than Python ;-) But while characters are integers, words are not (at least in [format] terms); for this purpose, different code will have to be written. ---- [Arts and crafts of Tcl-Tk programming]