Tcl Part I · Module 3 · Values, Variables, and Expressions
incr: Counting Without expr
Counting is common enough that Tcl gives it a command of its own. incr adds to a variable in place, which means no expression, no braces decision, and less to read. It is a small command and this is a short chapter, but it does two things that are not obvious from the name: it will happily create a variable that does not exist yet, and it refuses anything that is not a whole number. Both are worth knowing before you rely on it.
Foundation9 min readTclPart IValuesincrCounters
Part I · Module 3 · Chapter 3.9 · incr: Counting Without expr
1. The Command
set errors 0
incr errors
puts "after incr: $errors"after incr: 1incr takes a variable name and adds one to it. Note there is no $ on the name — incr changes the variable, so it needs the name, not the value. Same shape as set.
The long way round would be:
set errors [expr {$errors + 1}]Both work. incr is shorter, says what it means, and has no expression in it — so there is no bracing decision to get wrong. For counting, prefer it.
2. Any Step, Including Negative
A second argument sets the step:
set errors 0
incr errors
puts "after incr: $errors"
incr errors 5
puts "after incr 5: $errors"
incr errors -2
puts "after incr -2: $errors"after incr: 1
after incr 5: 6
after incr -2: 4There is no separate decrement command. A negative step is how you count down.
3. It Returns the New Value
Like set, incr hands back what it produced:
set count 4
puts "incr returns: [incr count]"
puts "count is now: $count"incr returns: 5
count is now: 5Useful when you want to count and use the number in one step, though two plain lines are usually clearer.
4. It Creates a Missing Variable
Here is the first thing that surprises people:
incr fresh
puts "fresh = $fresh"
incr other 7
puts "other = $other"fresh = 1
other = 7Neither variable existed. incr treated the missing value as zero and created the variable.
That is convenient — you can count without initialising first. It is also a hazard, because a typo in the variable name will not produce an error:
set error_count 0
incr eror_count ;# typo, and Tcl is perfectly happy
puts "error_count = $error_count"
puts "eror_count = $eror_count"error_count = 0
eror_count = 1No error, two variables, and a count that stays at zero forever. Compare this with reading a misspelled variable, which fails immediately — Chapter 3.2 §8.
5. It Requires an Integer
The second surprise:
set x "abc"
incr xexpected integer but got "abc"Expected. But so is this:
set x 1.5
incr xexpected integer but got "1.5"incr does whole numbers only. A float is an error, not a rounded result.
If you are accumulating a non-integer quantity, use expr:
set total 0.0
set total [expr {$total + 1.5}]
set total [expr {$total + 2.25}]
puts "total = $total"total = 3.75The step may also not be a float — incr x 0.5 fails the same way.
6. The Shape You Will Write Most
A counter has three parts, and they are usually spread across a script:
set checked 0
set failed 0
incr checked
incr checked
incr failed
incr checked
puts "checked $checked, failed $failed"checked 3, failed 1Initialise, increment where the event happens, report at the end. Once you reach Module 9 the increments will sit inside a loop, but the shape is this.
7. Common Mistakes
Writing incr $count. That increments the variable named by the value of count. Use incr count.
Relying on auto-creation. It hides typos. §4.
Expecting it to handle decimals. §5. Use expr.
Looking for a decrement command. incr x -1.
Using expr for simple counting. It works, but incr is clearer and has no bracing question.
8. Exercises
Exercise 1 — count up and down. Start a variable at 10. Increment by 1, then by 5, then by -3, printing after each. Predict each value first.
Exercise 2 — see the auto-creation. Increment a variable you never set, and print it. Then explain in one sentence why this is both convenient and risky.
Exercise 3 — reproduce the typo bug. Write the §4 typo example. Confirm there is no error. Then say what you would have to do to notice this in a real script.
Exercise 4 — meet both errors. Trigger incr on a value of abc and on a value of 2.5. Are the two messages the same shape? What does that tell you about what incr checks?
Exercise 5 — accumulate a decimal. Add 0.1 to a running total five times, then print it. Which command did you have to use, and why could incr not do it?
Exercise 6 — two counters. Write a script that counts how many of the values 5 12 7 20 3 are greater than 10, without a loop — just repeat the comparison by hand using if and incr. The point is the counter shape, not the comparison.
9. Remember
incr nameadds one to a variable in place. No$on the name.- A second argument sets the step, and a negative step counts down. There is no decrement command.
- It returns the new value.
- It creates a variable that does not exist, starting from zero — convenient, and it hides typos.
- Initialise counters anyway. One line, and the script documents itself.
- It requires whole numbers. A float is an error, not a rounding. Use
exprfor decimals. - Prefer it to
exprfor counting — shorter, clearer, and no bracing decision.
Next: the arithmetic result that catches more people than any other in Tcl.
Where this fits
Part of the Tcl curriculum.
