Version 7 of More compact "for" loop

Updated 2017-04-26 15:12:38 by LarrySmith

Typing out a "for" loop is just getting to be a drudge. Eventually, I decided to just tighten it up a bit.

The syntax is "do var range script" where "range" is specified like 1..10 - and you can add an 'x' and a step if needed: 1..10x2. It will also count backwards if the starting value is higher than the ending one, changing the sign of the step value for you.

 do i 0..10 {puts "value of i is $i"}

 do j 10..0x2 {puts "value of j is $j}

"break" and "continue" work as expected, since it's just translated to the equivalent "for" loop

I use split to handle the parsing and ran into a nasty limitation I didn't find at all obvious. Split splits on any of the split characters, it has no concept of using some character combination to split. So I fixed that, too, adding a means of translating multiple character strings in a list as a way to split. I called it "chop". It has a limit of no more than 9 different strings to use for the operation since I could only figure out 9 regular characters to map to that I thought wouldn't interfere.

Ideally, there should be a "parse" function to handle string->list conversions. In the case of ranges, something like "parse list {.. x} from to step" would handle parsing the range easily.

  proc do {var range loop} {
    lassign [chop $range ".. x"] from to by
    set cond <
    if {$by eq ""} {set by 1}
    if {$to<$from} {set by [= {-$by}]; set cond >=}
    set script "for \{set $var $from\} \{\$$var$cond$to\} \{incr $var $by\} \{"
    set script "${script}$loop\}"
    uplevel $script
  }


  # fixing split - won't split using string of chars as markers
  set splitchars {! @ # % ^ * | ~ `}

  proc chop{list marks} {
    set sp $::splitchars; set map {}
    foreach mark $marks {set map "$map $mark [hd sp]"}
    set list [string map $map $list]
    return [split $list $::splitchars]
  }

EF: Where can we find map, ^^, each and ^?

Actually, they're built-ins. Forgot to remove my "smithisms" when I posted. Fixed above.