100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Tcl Data Types and Lists

How Tcl's 'everything is a string' model supports lists, arrays, and dictionaries, and the core commands for building and manipulating them.

FoundationsIntermediate10 min readJul 10, 2026
Analogies

Everything Is a String — With Cached Internal Representations

Tcl's famous 'everything is a string' rule describes the language's semantics, not its implementation: internally, every value is a Tcl_Obj that carries both a string representation and, lazily, a cached native representation (an integer, a double, a list, a hash table for a dict) so that repeatedly using a value as, say, a list doesn't require re-parsing the string every time. This dual-representation design is why lappend mylist newItem is efficient even for large lists — Tcl mutates the cached list representation in place rather than reformatting and reparsing a giant string — while still guaranteeing that puts $mylist always produces a valid, well-quoted string form.

🏏

Cricket analogy: Just as a scorecard is officially a printed sheet but the scorer also keeps a running mental tally so they don't recount every ball from scratch, a Tcl_Obj keeps an official string form plus a cached internal representation so it doesn't re-parse from scratch every time.

Lists: Tcl's Core Data Structure

A Tcl list is just a specially formatted string where elements are separated by whitespace, with curly braces used to group any element that itself contains spaces or special characters, e.g. {apple banana {cherry pie}} is a 3-element list whose third element is itself the string cherry pie. The list command builds a properly quoted list from arguments (list apple banana "cherry pie" produces apple banana {cherry pie}), llength returns the number of elements, and lindex mylist 2 returns the element at index 2 (zero-based), all of which correctly handle nested braces rather than requiring you to hand-write list syntax yourself.

🏏

Cricket analogy: Just as a batting order lists eleven names in sequence, with a specific pairing like 'Rohit Sharma, Shubman Gill' still counting as two separate list entries, a Tcl list like {apple banana {cherry pie}} treats cherry pie as one grouped entry because of its braces.

Manipulating Lists

lappend mylist newItem appends an element and updates the variable in place; lsort mylist returns a sorted copy (with -integer, -real, or -dictionary options for non-lexicographic ordering); and lsearch mylist target returns the index of the first matching element, or -1 if not found. foreach item $mylist { ... } iterates over each element of a list, while split converts a delimited string into a list (split "a,b,c" "," yields a b c) and join performs the inverse, converting a list back into a delimited string (join {a b c} "-" yields a-b-c).

🏏

Cricket analogy: Just as a team manager appends a new signing to the squad list without rebuilding the whole roster from scratch, lappend mylist newItem adds an element to a Tcl list in place without rebuilding the whole list.

Arrays and Dictionaries

Tcl arrays are associative (hash-table-like), created implicitly with set myarray(key) value, where key can be any string, not just an integer, and array names myarray returns the list of all keys currently set. Since Tcl 8.5, the dict command provides a more modern, ordered key-value structure that, unlike an array, is itself an ordinary Tcl value that can be stored in a variable, passed to a proc, nested inside another dict, or returned from a command — dict create name Ada age 36, dict get $d name, and dict set d age 37 are the core operations for building, reading, and updating one.

🏏

Cricket analogy: Just as a scorer keeps a per-player runs tally keyed by player name rather than a fixed batting-order slot, a Tcl array like runs(kohli) is keyed by an arbitrary string rather than a fixed numeric index.

tcl
# Lists
set fruits [list apple banana "cherry pie"]
puts [llength $fruits]        ;# 3
puts [lindex $fruits 2]        ;# cherry pie
lappend fruits mango
puts [lsort $fruits]

# split / join round trip
set csvLine "Ada,36,Engineer"
set fields [split $csvLine ","]
puts [join $fields " | "]       ;# Ada | 36 | Engineer

# dict (ordered key-value)
set person [dict create name "Ada" age 36]
dict set person age 37
puts "[dict get $person name] is [dict get $person age]"

An unbalanced or misplaced brace inside a list element silently corrupts the list rather than raising an immediate error at the point you'd expect. Always build lists with list, lappend, or dict create instead of hand-writing brace-quoted strings; if you must construct one by hand, verify it with llength — a well-formed n-element list should always report exactly n.

  • Every Tcl value is a Tcl_Obj with both a canonical string form and a lazily cached native representation for efficiency.
  • A Tcl list is a specially formatted string; braces group multi-word elements into a single list item.
  • list, llength, and lindex build and inspect lists safely without hand-writing list syntax.
  • lappend grows a list in place; lsort returns a sorted copy; lsearch finds an element's index.
  • split turns a delimited string into a list; join turns a list back into a delimited string.
  • Tcl arrays are associative, keyed by arbitrary strings via set myarray(key) value and enumerated with array names.
  • dict (Tcl 8.5+) is an ordered key-value structure that is itself a first-class value, usable anywhere a normal Tcl value is.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#TclTkStudyNotes#TclDataTypesAndLists#Tcl#Data#Types#Lists#DataStructures#StudyNotes#SkillVeris