Skip to content
VLSI Mentor

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:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
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:

  1. Work out where each word starts and ends.
  2. Turn each word into its final value.
  3. 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.

Three stages left to right: the source line puts hello, then the line split into two words, then Tcl running the command named by the first word with the second word as its argument.The lineputs "hello"Two words1: puts · 2: helloTcl runs itcommand puts, given hello12
Figure 1 — one line of Tcl, read in three stages. The line is split into words, each word becomes a value, and the first value names the command that runs. Every chapter in this module explains one part of this picture.

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:

Azvya Education Pvt. Ltd.VLSI Mentor
show.tcl
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"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
received 2 word(s)
  word 1: two
  word 2: words
received 1 word(s)
  word 1: two words

Look 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:

Azvya Education Pvt. Ltd.VLSI Mentor
commands.tcl
foreach name {if set proc while puts expr} {
    puts [format "%-6s -> %s" $name [info commands $name]]
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
if     -> if
set    -> set
proc   -> proc
while  -> while
puts   -> puts
expr   -> expr

info 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:

Azvya Education Pvt. Ltd.VLSI Mentor
what-if-gets.tcl
proc my_if {condition body} {
    puts "word 1 (condition): $condition"
    puts "word 2 (body):      $body"
}

set count 0
my_if {$count == 0} {puts "zero"}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
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.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
puts "starting the run"
set count 0
string length "hello"
puts [string length "hello"]
  • puts "starting the run" — two words. puts names the command. The quotes make the message one word.
  • set count 0 — three words. set names the command, and gets count and 0.
  • string length "hello" — three words. string names the command. length is just its first argument, which is why string has 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:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
puts hello
puts "hello there"
set greeting "good morning"
string toupper hello

Exercise 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, set and proc are 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.