increment a variable http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/incr.html incr variable ?increment? The variable must exist before the ''incr'' call, and must have an integer value. The increment must also be an integer and defaults to 1 if not specified, with the result being that incr i and set i [expr {$i + 1}] are nearly equivalent. The difference of course has to do when the assumptions are violated - if i ''isn't'' an integer, then the second expression works whereas the first raises an error that you have to catch unless you want the program to terminate. Note that the increment can be a negative number - allowing you to 'increment' decrementally ;-). ---- Note also that the increment may be zero. This sounds useless, but has the side effect that the variable is type-checked to be integer, which avoids endless loops like for {set i 0} {$i<$max} {incr i} {...} when ''max'' is a non-numeric string whose first character sorts higher than "9". If ''max'' comes in as user-supplied parameter, this may well happen... A simple ''incr max 0'' safeguards that it must be an integer. ([RS]) ---- Work is underway to add more 64 bit support into Tcl. Even when this happens, the increment value is supposedly going to continue to be limited to 32 bits due to the far reaching ramifications of changes needed. ---- [RS] had a half-baked idea these days - extend [incr] to also work on characters (like in C), so we could write: for {set letter "A"} {$letter<="Z"} {incr letter} {...} [rmax] pointed rightly out that ambiguities come up as soon as the character is a digit: ''set i 9; incr i'' would make it 10, not ":" as expected - so maybe with a '''-char''' switch which still looks better than set letter [format %c [expr {[scan $letter %c]+1}]] ---- Is there anything peculiar that happens with this in regards to encoding? Will the incrementing be of the utf8 byte value? Are there multi-byte character issues with regards to incrementing? What happens at wrap around time if only 8 bits are being used? Wrap to 0? Is this a 7 or 8 bit value? - [RS]: To Tcl (since 8.1), all characters are Unicodes and potentially 16 bits wide (this may have to change to 32), which mostly are stored as UTF characters, 1..3 bytes wide. I would propose that '''incr -char''' reacts like the ''format..expr..scan'' code above, just faster, and might throw an error if crossing 0xFFFF. Incrementing strings of more than a char wide seems of little use to me, could raise an error as well. 1. Are all 16 bit bytes valid unicode characters? ''(No. Some codes (0xFFFE, 0xFEFF, others?) are explicitly not characters, and others are non-spacing diacriticals that shouldn't be used on their own. -SCT)'' 1. When I was talking about multi-byte characters, I was referring to the 2 and 3 byte long sequences for a unicode character. However, now that you mention it, I '''would''' like to be able to say set name "/tmp/filename0" incr name and have the file name go from filename0 to filename9, then filenamea-z, etc. - [RS]: Hm. A long way from "9" to "a" in ASCII or Unicode.. How about using the self-incrementing proc proc intgen {{seed 0}} { set self [lindex [info level 0] 0] proc $self "{seed [incr seed]}" [info body $self] set seed } ;# RS from [Braintwisters], and then write (where after ''filename9'' will come ''filename10''): set name "/tmp/filename[intgen]" ---- Here is a corresponding decrement function: proc decr { int { n 1 } } { if { [ catch { uplevel incr $int -$n } err ] } { return -code error "decr: $err" } return [ uplevel set $int ] } [RS] wonders what the advantages against proc decr {var {n 1}} {uplevel 1 [list incr $var -$n]} are (or against just writing ''incr i -1'')? [Martin Lemburg]: I love readable code and using '''''decr var 1''''' is more readable than '''''incr var -1''''', or am I wrong? Isn't it worth to discuss [readability of code]? [DKF]: Good bonus to readability, not so good for speed (the '''incr''' version will be bytecoded much more efficiently.) Tricky trade-off that... ---- This '''tolerant incrementer''' creates the variable if necessary, and initializes it with 0: proc inc {varName {amount 1}} { upvar 1 $varName var if {![info exists var]} {set var 0} incr var $amount } [KPV] You can avoid the [info exists] altogether by doing: set var [expr [append var + $amount]] Unfortunately, while this is tighter, it is slower due to [shimmering].' [Lars H]: The need to parse the expression generated probably also contributes to that being slower. Another idiom is if {[catch {incr var $amount}]} then {set var $amount} If the variable exists most of the time then this is faster than the [[info exists]] approach. ---- '''Incrementing doubles''' as well as ints can be done like this: proc += {varName {amount 1}} { upvar 1 $varName var set var [expr {$var+$amount}] } ;# RS ---- [Tcl syntax help] | [Arts and crafts of Tcl-Tk programming] | [Category Command] from [Tcl]