Skip to content
VLSI Mentor

Tcl Part I · Module 3 · Values, Variables, and Expressions

Truth in Tcl: What Counts as True and False

Tcl has no boolean type, because values do not carry types at all. What it has instead is a set of words and numbers that count as true or false when something reads a value as a truth value. The list is short and worth knowing exactly. The more important half of this chapter is what happens to everything not on the list, because the answer is not what you will expect if you have written Python or JavaScript — and the Tcl behaviour is genuinely better, for a reason worth understanding.

Foundation11 min readTclPart IValuesBooleansConditions

Part I · Module 3 · Chapter 3.6 · Truth in Tcl: What Counts as True and False

1. There Is No Boolean Type

Chapter 3.1 said values carry text and commands decide what it means. Truth is one such reading.

So there is no true object and no boolean variable. There is a set of values that, when something reads them as a truth value, count as true or false.

2. The Accepted Words

Azvya Education Pvt. Ltd.VLSI Mentor
words.tcl
foreach v {1 0 yes no true false on off} {
    puts [format "%-6s -> %s" $v [expr {$v ? 1 : 0}]]
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
1      -> 1
0      -> 0
yes    -> 1
no     -> 0
true   -> 1
false  -> 0
on     -> 1
off    -> 0

Four pairs: 1/0, yes/no, true/false, on/off.

They are case-insensitive:

Azvya Education Pvt. Ltd.VLSI Mentor
case.tcl
foreach v {YES Off TRUE} {
    puts "$v -> [expr {$v ? 1 : 0}]"
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
YES -> 1
Off -> 0
TRUE -> 1

3. Numbers

Any number works, and the rule is the familiar one — zero is false, anything else is true:

Azvya Education Pvt. Ltd.VLSI Mentor
numbers.tcl
foreach v {2 -1 0.0 0.5} {
    puts "$v -> [expr {$v ? 1 : 0}]"
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
2 -> 1
-1 -> 1
0.0 -> 0
0.5 -> 1

Note -1 is true. "True" does not mean "positive"; it means "not zero".

And 0.0 is false, so a floating-point zero behaves like an integer zero. That is worth knowing because a computed value that lands exactly on zero will take the false branch, while one that lands on 0.0000001 will not.

4. Everything Else Is an Error

Here is where Tcl differs from the languages you are most likely coming from:

Azvya Education Pvt. Ltd.VLSI Mentor
not-boolean.tcl
puts [expr {"hello" ? 1 : 0}]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
expected boolean value but got "hello"

Not false. An error.

And the one that catches Python programmers hardest:

Azvya Education Pvt. Ltd.VLSI Mentor
empty.tcl
puts [expr {"" ? 1 : 0}]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
expected boolean value but got ""

The empty string is also an error.

Language"" in a condition"hello" in a condition
Pythonfalsetrue
Tclerrorerror

If you write Tcl expecting Python's rules, you will write conditions that look sensible and stop the script.

5. Why the Error Is the Right Behaviour

It is tempting to see this as Tcl being unhelpful. It is the opposite.

Consider a condition that tests a value you misspelled, or a field that failed to parse and came back empty. Under Python's rules the condition quietly evaluates to false and the script takes the wrong branch — silently, with no indication anything went wrong. You find out later, from the output, if at all.

Tcl stops and tells you the value was not a truth value. A bad condition becomes a loud failure rather than a silent wrong answer.

This is the same design choice as reading a missing variable being an error — Chapter 3.2 §8. Tcl prefers to fail where the problem is.

6. Asking Without Risking the Error

If a value might not be a truth value, test it first — the same discipline as Chapter 3.5:

Azvya Education Pvt. Ltd.VLSI Mentor
is-boolean.tcl
foreach v {yes 1 maybe ""} {
    puts [format "%-6s -> %s" "<$v>" [string is boolean -strict $v]]
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
<yes>  -> 1
<1>    -> 1
<maybe> -> 0
<>     -> 0

string is boolean -strict returns 1 only for values Tcl would accept. And as in Chapter 3.5, write -strict — without it the empty string passes.

A guard for a configuration value that should be a yes/no flag:

Azvya Education Pvt. Ltd.VLSI Mentor
guard.tcl
set flag "maybe"

if {[string is boolean -strict $flag]} {
    puts "verbose mode: [expr {$flag ? "on" : "off"}]"
} else {
    puts "not a yes/no value: $flag"
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
not a yes/no value: maybe

7. Where Truth Values Come From

Comparisons produce them, which is how conditions normally get written:

Azvya Education Pvt. Ltd.VLSI Mentor
comparisons.tcl
set count 3

puts "count > 0   -> [expr {$count > 0}]"
puts "count == 10 -> [expr {$count == 10}]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
count > 0   -> 1
count == 10 -> 0

Comparisons return 1 or 0. That is why you rarely write yes or on in a condition yourself — you write a comparison, and it produces a value already on the accepted list.

The words matter most for configuration: a flag read from a file or supplied by a user is far more likely to be the text yes than the number 1, and Tcl accepting both is what makes that convenient.

8. Common Mistakes

Expecting an empty string to be false. It is an error. §4.

Expecting a non-empty string to be true. Also an error. §4.

Testing a value that might be text without checking. Use string is boolean -strict first. §6.

Omitting -strict. Same trap as Chapter 3.5 — the empty string passes.

Assuming only 1 and 0 work. Four pairs of words work, case-insensitively, plus any number. §2 and §3.

Thinking -1 is false. Not zero means true. §3.

9. Exercises

Exercise 1 — the full set. Write a loop that prints the truth value of all eight accepted words plus three capitalised variants. Confirm the pairs behave as you expect.

Exercise 2 — meet the error. Evaluate a condition on the value hello, then on the empty string. Read both messages. Write one sentence saying why this is better than silently returning false.

Exercise 3 — the Python habit. This line looks reasonable and is wrong in Tcl:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
set name ""
puts [expr {$name ? "has a name" : "no name"}]

Run it, then rewrite it so it works, testing explicitly for an empty value.

Exercise 4 — numbers. Predict the truth value of 0, 0.0, -1, 0.0001 and 2. Then check.

Exercise 5 — a safe flag reader. Write a script that takes a variable flag and prints enabled, disabled, or invalid setting: <value>. Test it with yes, off, 1, maybe and "".

Exercise 6 — where do truth values come from? Without using any of the eight words, write three conditions that produce 1 and three that produce 0.

10. Remember

  • There is no boolean type. Truth is a reading of a value, like arithmetic is.
  • Four pairs are accepted: 1/0, yes/no, true/false, on/off — case-insensitively.
  • Any number works: zero is false, anything else is true, including negatives. 0.0 is false.
  • Everything else is an error, including the empty string. Not false — an error.
  • That is deliberate and better. A bad condition fails loudly instead of silently taking the wrong branch.
  • Do not rely on truthiness. Test explicitly for what you mean, such as $name ne "".
  • string is boolean -strict asks safely — and -strict is required, as always.
  • Comparisons return 1 or 0, which is where most conditions get their values.

Next: the command that does arithmetic, and why Tcl needs one at all.

Where this fits

Part of the Tcl curriculum.