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

Arrays and Dictionaries in Tcl

Understand Tcl's associative arrays and the modern dict command, and learn when to reach for each key-value structure.

Control Flow & ProceduresIntermediate10 min readJul 10, 2026
Analogies

Associative Arrays in Tcl

A Tcl array is a variable that holds a collection of key-value pairs rather than a single scalar value -- you create one implicitly by assigning to an indexed name like set scores(Alice) 90, or in bulk with array set scores {Alice 90 Bob 85 Carol 92}. Unlike lists or scalars, an array is not itself a value you can pass around; it's a special kind of variable, and each name(key) reference is really addressing one element of that variable's underlying hash table. This makes arrays a natural fit for lookup tables and named collections of related data, similar to associative arrays or hash maps in other languages.

🏏

Cricket analogy: set scores(Kohli) 82 mirrors a scorekeeper's tally sheet where each player's name is the lookup key and their run total is the stored value -- you look up 'Kohli' directly instead of scanning through an ordered list of all scores to find his.

Working with Arrays

array names scores returns a list of every key currently in the array, in unspecified order unless you sort it, array get scores returns a flat key-value list suitable for feeding back into array set elsewhere, and array size scores reports how many elements it holds. To visit every entry, combine array names with foreach: foreach key [array names scores] {puts "$key: $scores($key)"}. array exists scores checks whether a variable is an array at all, and array unset scores clears it, both useful for defensive checks before operating on a possibly-undefined array.

🏏

Cricket analogy: foreach key [array names scores] {puts "$key: $scores($key)"} printing every player's score mirrors reading out a full scorecard name by name, while array exists scores checking before use mirrors a scorer verifying the scoresheet actually exists before trying to read from it.

Introducing dict

dict is Tcl's more modern, ordered key-value structure, and critically it's a value, an ordinary string with a well-defined internal representation, not a special variable type like an array. dict create k1 v1 k2 v2 builds a new dict, dict set d key value returns an updated dict with that key set (or updates a dict-valued variable in place when given a variable name), and dict get $d key retrieves a value, raising an error if the key is absent. Because dicts can hold other dicts as values, they naturally represent nested/structured data like JSON-style configuration, whereas plain arrays cannot directly nest.

🏏

Cricket analogy: dict create name Kohli team India runs 82 building a structured player record mirrors a modern digital scorecard app storing a player's full profile as one nested object, and dict get $player team retrieving just the team field mirrors tapping on a player's card to see one specific stat.

Choosing Between array and dict

The core distinction is that an array is a variable, you can't pass 'the array' as a single argument to a procedure without upvar or array get/array set round-tripping, while a dict is a value that can be stored in a scalar variable, passed to a procedure, returned from a function, or nested inside a list or another dict, just like any string or number. For simple flat lookup tables inside a single scope, arrays remain idiomatic and are marginally faster for repeated single-key access; for anything that needs to be passed around, nested, or returned from a procedure, dict is almost always the better choice in modern Tcl (8.5+).

🏏

Cricket analogy: Passing a dict of match stats to proc summarize {stats} {...} is like handing a fully compiled scorecard printout to a commentator, a self-contained value they can read from directly, whereas an array is more like the live scoreboard itself, which you can't hand someone; you'd have to give them upvar access to it.

tcl
# Array: flat key-value lookup table
array set scores {Kohli 82 Rohit 45 Bumrah 3}
foreach player [array names scores] {
    puts "$player: $scores($player)"
}

# Dict: nested, portable value
set player [dict create name Kohli team India stats {runs 82 balls 49}]
puts [dict get $player team]
puts [dict get $player stats runs]

proc summarize {playerDict} {
    return "[dict get $playerDict name] scored [dict get $playerDict stats runs] runs"
}
puts [summarize $player]

Because a dict is an ordinary string value, it preserves insertion order when you iterate it with dict for {key value} $d {...}, unlike a plain array whose array names order is unspecified (implementation-defined by the underlying hash table) unless you explicitly sort the returned list.

An array cannot be passed to a procedure as a single argument the way a dict can -- proc show {arr} {puts $arr(key)} will not work as expected because arr inside the proc is just a scalar copy of whatever string was passed, not a reference to the caller's array. To operate on a caller's array inside a procedure, you must use upvar 1 arrName localName, or convert it with array get/array set at the boundary. Dicts avoid this problem entirely because they're regular values.

  • A Tcl array is a variable holding key-value pairs, created via set arr(key) value or array set arr {...}.
  • array names, array get, array size, array exists, and array unset are the core commands for inspecting and managing arrays.
  • dict is an ordered key-value value type, an ordinary string, not a special variable, built with dict create and read with dict get.
  • Dicts can nest other dicts as values, naturally representing structured/hierarchical data; plain arrays cannot nest directly.
  • Because arrays are variables, passing one into a procedure requires upvar or round-tripping through array get/array set.
  • Dicts, being values, can be passed to and returned from procedures, stored in variables, and nested inside lists or other dicts freely.
  • For simple flat lookup tables in one scope, arrays are idiomatic; for anything passed around or nested, prefer dict.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#TclTkStudyNotes#ArraysAndDictionariesInTcl#Arrays#Dictionaries#Tcl#Associative#DataStructures#StudyNotes#SkillVeris