Tcl Part I · Module 2 · The Tcl Execution Model
Everything Is a Command: command + words
Module 1 told you that Tcl has one grammar rule: a command name followed by words. This chapter makes that rule precise and shows you how to use it. You will see a command receive its words, and you will see that if gets its condition and its body the same way — as ordinary words. Once you can look at a line and name its words, the rest of Module 2 is about one question: what each word turns into before the command runs.
Foundation11 min readTclPart IExecution ModelCommandsWords
Part I · Module 2 · Chapter 2.1 · Everything Is a Command: command + words
1. Why This Module Comes Before Everything Else
Most Tcl tutorials teach commands first. The reader learns set, then puts, then if. Then something quoted behaves strangely, and the tutorial explains quoting as a list of rules to memorise.
We are doing it the other way round. Tcl has one rule about how a line is read. Almost every Tcl surprise is that rule working correctly on input you did not expect. Learn the rule now and you will not need the list.
This chapter installs the first half of the rule: words. The rest of the module adds what happens to them.
2. The Rule
A line of Tcl is a command name, then words, separated by spaces:
puts "hello"Two words. The first word, puts, names the command to run. The second word is given to it.
Tcl does three things with that line:
- Work out where each word starts and ends.
- Turn each word into its final value.
- Look up the command named by the first word, and run it with the rest.
Step 2 is substitution, and it is Chapters 2.4 to 2.6. This chapter is about step 1 and step 3.
3. Seeing the Words
Words are invisible. You cannot see them in the source, and that is why this module needs a tool.
Here is one. It is a command that reports the words it was given:
proc show {args} {
puts "received [llength $args] word(s)"
set i 1
foreach w $args {
puts " word $i: $w"
incr i
}
}
show two words
show "two words"received 2 word(s)
word 1: two
word 2: words
received 1 word(s)
word 1: two wordsLook at the difference. The same six characters, two words, arrived as two words the first time and one word the second time. The quotes changed how many arguments the command got.
That is the whole of Module 2 in one example.
4. if Is a Command Too
This is the part that sounds like a technicality and is not.
In C or Python, if is part of the language. The compiler knows about it before any function is looked up. In Tcl there is no such special case. if is a command, sitting in the same table as puts.
Ask Tcl:
foreach name {if set proc while puts expr} {
puts [format "%-6s -> %s" $name [info commands $name]]
}if -> if
set -> set
proc -> proc
while -> while
puts -> puts
expr -> exprinfo commands found every one of them the same way it found puts. There is no separate list of keywords, because there are no keywords.
5. What if Actually Receives
If if is an ordinary command, then its condition and its body must be ordinary words. We can check that directly, by writing a command that takes two words and prints them:
proc my_if {condition body} {
puts "word 1 (condition): $condition"
puts "word 2 (body): $body"
}
set count 0
my_if {$count == 0} {puts "zero"}word 1 (condition): $count == 0
word 2 (body): puts "zero"Read that output carefully, because two things in it matter.
The condition arrived as text. my_if received the characters $count == 0. It did not receive true or false. Something has to evaluate that text later.
The body arrived as text too. my_if received the characters puts "zero". The puts did not run. It is just a word, sitting there, waiting for something to run it.
That is exactly what the real if gets. It receives a condition to evaluate and a body to run, both as plain words. Then it decides whether to run the body.
6. Why Tcl Was Built This Way
A language with keywords needs a parser that knows them. Adding a new control structure means changing the language.
Tcl has no keywords, so a new command is just a new entry in a table. if was added that way. So was foreach. So is anything you write yourself with proc, and so are the commands an application adds when it embeds Tcl — which is Chapter 1.3, and which is why that chapter mattered.
The cost is that Tcl cannot give if special treatment. The benefit is that nothing is special, so one rule explains everything.
7. Reading a Line
Try reading these as words. For each line, say how many words there are and which one names the command. The answers follow.
puts "starting the run"
set count 0
string length "hello"
puts [string length "hello"]puts "starting the run"— two words.putsnames the command. The quotes make the message one word.set count 0— three words.setnames the command, and getscountand0.string length "hello"— three words.stringnames the command.lengthis just its first argument, which is whystringhas so many subcommands.puts [string length "hello"]— two words. The brackets make everything inside them produce one value. Chapter 2.5 is about that.
If the third one surprised you, it is worth sitting with. string length is not a two-word command name. It is the command string, told to do length.
8. Common Mistakes
Thinking a space is just formatting. It is not. A space ends a word, which means it ends an argument. Chapter 2.3 is entirely about this.
Thinking if needs special syntax. It does not. If you can call a command, you can call if. The braces are not if syntax; they are ordinary grouping.
Thinking brackets are array indexing. They are not. In Tcl, [...] runs a command and uses its result. Nothing in Tcl indexes with brackets.
Expecting a keyword list. There is not one worth learning. There is a command list, and you can ask for it with info commands.
9. Exercises
Exercise 1 — count the words. Without running anything, say how many words each line has and which names the command:
puts hello
puts "hello there"
set greeting "good morning"
string toupper helloExercise 2 — check yourself. Save the show procedure from §3 and run each of those four lines through it, replacing the command name with show. For example, show "hello there". Were you right?
Exercise 3 — the body is just a word. Run the my_if example from §5, then change the body to puts "something else". Confirm the new text is printed as a word and still does not run. Explain in one sentence why it does not run.
Exercise 4 — find a command you did not know was one. Pick three names from this chapter and run info commands <name> on each. Then try a name you invented. What comes back, and what does that tell you?
10. Remember
- A line of Tcl is a command name followed by words, separated by spaces.
- The first word names the command. The rest are given to it as arguments.
if,while,setandprocare all commands. Tcl has no keywords, so nothing gets special treatment.- A command receives its condition and its body as ordinary words, unchanged. It decides what to do with them.
- Quoting changes how many words there are, and therefore how many arguments the command gets.
[...]is not indexing. It runs a command. Chapter 2.5.
The next chapter takes the three stages from Figure 1 and makes them exact — including the one rule that explains most Tcl surprises.
Where this fits
Part of the Tcl curriculum.
