proc toggle {v} { uplevel [concat set $v \[expr \[set $v\] ^ 1\]] } % set state 0 0 % toggle state 1 % toggle state 0 [RS] has this alternative: proc toggle varName { upvar 1 $varName var set var [expr {!$var}] } Using the ''not'' operator (!) has, apart from being straightforward, the advantage that it also accepts the other allowed forms for truth values (yes, no, on, off, true, false). Also, as every non-zero int or double implies 'true' for [expr], the other alternatives may lead to subtle bugs. ''Not on tcltk 8.3.2'', where the ! operator to expr gives me can't use non-numeric string as operand of "!" That's why [KPV]'s version is #1 for me. ''--[Ro]'' [escargo] has this alternative: proc toggle varName { upvar 1 $varName var set var [expr {1 - $var}] } ''This is a clearly inferior alternative (probably on the basis of performance, but also because of the subtle bugs), but I wanted to include it for completeness. In fact, I found a bug in a Fortran compiler once where code optimization turned the expression'' TOGGLE = 1 - TOGGLE ''into a decrement instruction. That made my Fortran program misbehave in mysterious ways until I figured out what was going wrong.'' [KPV] has yet another alternative proc toggle varName { upvar 1 $varName var set var [expr {$var ? 0 : 1}] } ---- [KPV] not quite the same thing, but I've liked the following idiom for normalizing boolean values, i.e. converting all true values into 1, and all false values into 0: set b [expr {!!$b}] ---- [GPS]: when I started this page I should have thought about my code more. The lack of using upvar was a major mistake. I wrote a little script to compare the various solutions. catch {console show} proc gps_orig_toggle {v} { uplevel [concat set $v \[expr \[set $v\] ^ 1\]] } proc gps_toggle {vPtr} { upvar 1 $vPtr v set v [expr {$v ^ 1}] } proc rs_toggle {varName} { upvar 1 $varName var set var [expr {!$var}] } proc esc_toggle {varName} { upvar 1 $varName var set var [expr {1 - $var}] } proc kpv_toggle {varName} { upvar 1 $varName var set var [expr {$var ? 0 : 1}] } proc main {} { set gps_orig_v 0 puts GPSORIG_[time {gps_orig_toggle gps_orig_v} 9000] set gps_v 0 puts GPS_[time {gps_toggle gps_v} 9000] set rs_v 0 puts RS_[time {rs_toggle rs_v} 9000] set esc_v 0 puts ESC_[time {esc_toggle esc_v} 9000] set KPV_v 0 puts KPV_[time {kpv_toggle kpv_v} 9000] } main I've run the tests many times in Windows XP, and the results for the last three (now four) tend to be identical or vary by 1 microsecond per iteration. There doesn't seem to be a clear winner. [KPV] Same is true for win2k. There is a clear winner, and it's [KPV]'s version: proc kpv_toggle {varName} { upvar 1 $varName var set var [expr {$var ? 0 : 1}] } since this is the only one that works with all of tcl's wonderful boolean string variables, like true, false, yes and no. At least this is on tcltk 8.3.2 on my win98 (first ed). ''--[Ro]'' ---- 16feb04 [jcw] - Other ways to toggle 0/1's: set a [regexp 0 $a] set a [string match 0 $a] set a [string map {0 1 1 0} $a] ---- [SS] 16feb2004 - Another alternative is to let [if] to provide the way to check the current state. proc ifbased_toggle varname { upvar 1 $varname var set var [if {$var} {format 0} {format 1}] } ---- [MG] offers another alternative on March 3rd 2005 (which only works with 1/0, not yes/no, true/false, etc)... proc mg_toggle varName { upvar 1 $varName var set var [lindex "1 0" $var] } Seems to come up slightly slower (about 1-2 microseconds) than the others above, though. ---- [Jasp] would usually use [expr], but notes you could also use: proc jaspToggle {varName} { upvar 1 $varName variable set variable [string is false -strict $variable] } ---- [Category Example]