Tcl Part I · Module 6 · Lists
What a Tcl List Actually Is
Lists are the data structure Tcl is built around, and the first thing to understand about them is the thing most surprising to anyone arriving from another language: a list is not a separate kind of value. It is a string, written in a particular format, and the list commands are commands that read a string according to that format. This is not a technicality — it explains why lists compose so freely with text, why a value can be counted two different ways, and why building one carelessly produces something that is quietly not the list you meant.
Foundation12 min readTclPart IListsMental Model
Part I · Module 6 · Chapter 6.1 · What a Tcl List Actually Is
1. The Claim
A Tcl list is a string whose words follow list rules.
Not a string underneath. Not convertible to a string. It is one.
2. The Proof
set items [list a b c]
puts "the value: <$items>"
puts "string length: [string length $items]"
puts "llength: [llength $items]"
puts "equals \"a b c\"? [expr {$items eq "a b c"}]"the value: <a b c>
string length: 5
llength: 3
equals "a b c"? 1Read the last line again. [list a b c] produced a value that is exactly equal to the five characters a b c — compared with eq, which from Chapter 4.4 compares characters and never anything else.
There is no list object. There are five characters, and llength knows how to count the words in them.
3. This Is Chapter 3.1 Again
Chapter 3.1 established the model: a value carries text, and the command that reads it decides what it means. Lists are one such reading.
set v "clk 1 input"
puts "as text: [string length $v] characters, first character <[string index $v 0]>"
puts "as list: [llength $v] elements, first element <[lindex $v 0]>"as text: 11 characters, first character <c>
as list: 3 elements, first element <clk>One value, two commands, two entirely reasonable answers.
4. What "List Rules" Means
The format is the one you already know from Chapter 2.3 — the same word-splitting rules Tcl uses when reading a command:
- Whitespace separates elements.
- Braces group an element that contains spaces.
- Runs of whitespace count as one separator, unlike
split— Chapter 5.13 §5.
puts "simple: [llength {a b c}]"
puts "extra spaces: [llength {a b c}]"
puts "braced element:[llength {a {b c} d}]"
puts "nested: [lindex {a {b c} d} 1]"simple: 3
extra spaces: 3
braced element:3
nested: b cThe third list has three elements, the middle one being the two words b c held together by braces.
5. Not Every String Is a List
Here is the half the slogan leaves out:
set bad "a {b c"
puts [catch {llength $bad} message]
puts $message1
unmatched open brace in listAn unbalanced brace means the text cannot be read as a list, and llength says so rather than guessing.
So the accurate statement is:
Every list is a string. Not every string is a list.
Most ordinary text happens to be a valid list — "clk 1 input" is three elements, "hello" is one. It is braces and quotes that can make text unreadable as a list, which is precisely why Chapter 6.2 insists you build lists with list rather than by gluing text together.
6. Why This Design Is Useful
Because lists are strings, every command that accepts text accepts a list:
set items [list alpha beta gamma]
puts "as a list: [llength $items] elements"
puts "as text: [string toupper $items]"
puts "searched: [string first "beta" $items]"
puts "still a list:[llength [string toupper $items]]"as a list: 3 elements
as text: ALPHA BETA GAMMA
searched: 6
still a list:3The uppercase version is still a perfectly good three-element list, because uppercasing did not disturb the spaces.
In a language with a distinct list type you would be converting at every boundary. Here there is no boundary.
7. The Empty List
set empty {}
puts "llength: [llength $empty]"
puts "string length: [string length $empty]"
puts "is empty text? [expr {$empty eq ""}]"llength: 0
string length: 0
is empty text? 1The empty list and the empty string are the same value. {} and "" are two ways of writing it.
Most code uses {} when the intent is a list and "" when the intent is text. The convention communicates; Tcl does not distinguish.
8. Common Mistakes
Looking for a list type. There is none. §1.
Assuming any string can be used as a list. Unbalanced braces cannot. §5.
Building a list by gluing text together. Chapter 6.2 is entirely about why.
Mixing text operations and list operations on the same value carelessly. §6.
Expecting split and list parsing to agree on whitespace. They do not — Chapter 5.13 §5.
9. Exercises
Exercise 1 — prove it yourself. Build a three-element list with list, print it, and show with eq that it equals the plain text you would have typed.
Exercise 2 — two readings. For the value "a bb ccc", print the character count and the element count, and the first of each.
Exercise 3 — the rules. Predict the element count of each, then check: {x y z}, {x y z}, {x {y z}}, {{x y} {z}}, {}.
Exercise 4 — break it. Create a string with an unmatched brace and pass it to llength. Read the error. Then make it valid and confirm it works.
Exercise 5 — the composing edge. Take a three-element list, apply string map {" " "-"} to it, and print the new element count. Explain what happened.
Exercise 6 — empty. Show that {} and "" are the same value, using eq, llength and string length.
10. Remember
- A Tcl list is a string whose words follow list rules.
[list a b c]equals the charactersa b c. - There is no list type, and no conversion step between text and lists.
- List rules are the same word-splitting rules Tcl uses for commands — whitespace separates, braces group, runs of whitespace count once.
- Every list is a string; not every string is a list. Unbalanced braces cannot be read as one.
- Any text command accepts a list, which is why they compose freely.
- But a text operation can change the element count without an error. Do not alternate carelessly.
- The empty list and the empty string are the same value. Write
{}when you mean a list.
Next: the one command that builds a list correctly, and what happens when you do not use it.
Where this fits
Part of the Tcl curriculum.
