Skip to content
VLSI Mentor

Tcl Part I · Module 6 · Lists

lappend: Growing a List

Most lists in real scripts are not written out in the source — they are collected as the script runs, one element at a time, as files are found or lines are parsed or results are computed. This is the command for that, and it is one of only two in the module that change a variable rather than returning a new value. It is also the right answer to a mistake that is very easy to make: the obvious alternative of reassigning the variable each time is not merely slower, it produces a list with the wrong number of elements.

Foundation11 min readTclPart IListsBuildingCorrectness

Part I · Module 6 · Chapter 6.6 · lappend

1. The Command

Azvya Education Pvt. Ltd.VLSI Mentor
basic.tcl
set found {}

lappend found "alpha"
lappend found "beta"

puts "$found -> [llength $found] elements"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
alpha beta -> 2 elements

It takes a variable name — no $ — and adds to the end of the list it holds. Same shape as set, incr and append.

2. It Modifies the Variable

Azvya Education Pvt. Ltd.VLSI Mentor
in-place.tcl
set l {a b}

linsert $l 0 header
puts "after linsert: $l"

lappend l "c"
puts "after lappend: $l"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
after linsert: a b
after lappend: a b c

linsert returned a new list that was discarded. lappend changed l directly.

Only two commands in this module write to the variable: lappend and lset. Everything else returns a new list — a distinction Chapter 6.7 makes a point of.

3. It Quotes Correctly

This is Chapter 6.2's rule applied to growth:

Azvya Education Pvt. Ltd.VLSI Mentor
quoting.tcl
set found {}

lappend found "two words"
lappend found "other"

puts "<$found> -> [llength $found] elements"
puts "element 0: <[lindex $found 0]>"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
<{two words} other> -> 2 elements
element 0: <two words>

lappend added the braces. Two values in, two elements out, and the first one intact.

4. Several Values at Once

Azvya Education Pvt. Ltd.VLSI Mentor
several.tcl
set found {}

lappend found "a" "b c" "d"

puts "$found -> [llength $found] elements"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
a {b c} d -> 3 elements

Each argument becomes one element, each quoted as needed.

5. The Mistake It Prevents

The obvious alternative:

Azvya Education Pvt. Ltd.VLSI Mentor
wrong.tcl
set files {}

foreach f {report.txt "my notes.txt" data.csv} {
    set files "$files $f"
}

puts "elements: [llength $files]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
elements: 4

Four, from three filenames. The one containing a space split into two elements — Chapter 6.2 §1 happening once per iteration.

Azvya Education Pvt. Ltd.VLSI Mentor
right.tcl
set files {}

foreach f {report.txt "my notes.txt" data.csv} {
    lappend files $f
}

puts "elements: [llength $files]"
puts "second:   <[lindex $files 1]>"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
elements: 3
second:   <my notes.txt>

6. It Creates the Variable

Azvya Education Pvt. Ltd.VLSI Mentor
creates.tcl
lappend fresh "first"
puts "$fresh -> [llength $fresh] elements"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
first -> 1 elements

No set fresh {} needed. Like incr in Chapter 3.9 §4 and append in Chapter 5.10 §4, a missing variable is treated as empty.

And the same caution: a typo in the variable name quietly starts a second list rather than failing. Initialise with set found {} anyway — it costs a line and makes the starting point visible.

7. It Returns the New List

Azvya Education Pvt. Ltd.VLSI Mentor
returns.tcl
set l {a}
puts "returns: [lappend l "b"]"
puts "l is:    $l"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
returns: a b
l is:    a b

Occasionally useful, mostly ignored.

8. append and lappend Are Not the Same

Azvya Education Pvt. Ltd.VLSI Mentor
versus-append.tcl
set a {}
set b {}

lappend a "two words"
append  b "two words"

puts "lappend: <$a> -> [llength $a] elements"
puts "append:  <$b> -> [llength $b] elements"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
lappend: <{two words}> -> 1 elements
append:  <two words>   -> 2 elements

lappend added one element and quoted it. append added characters, and the result happens to read as two elements.

The rule from Chapter 5.10 §8: append for text you will print, lappend for a collection you will take apart again.

9. The Collecting Shape

Azvya Education Pvt. Ltd.VLSI Mentor
collecting.tcl
set matched {}
set skipped {}

foreach name {clk_tb reset data_tb payload} {
    if {[string match "*_tb" $name]} {
        lappend matched $name
    } else {
        lappend skipped $name
    }
}

puts "matched ([llength $matched]): $matched"
puts "skipped ([llength $skipped]): $skipped"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
matched (2): clk_tb data_tb
skipped (2): reset payload

Initialise to empty, append as you go, report counts at the end. This is the list counterpart of the counter shape from Chapter 3.9 §6, and it is how most real lists come into existence.

10. Common Mistakes

set l "$l $v". Wrong and slow. §5.

Writing lappend $found $v. The name goes in without a $.

Using append where you meant lappend. §8.

Not initialising. It works; a typo then silently builds a second list. §6.

Appending a list expecting it to merge. lappend l $other adds the whole list as one element. To join two lists you want concat or lappend l {*}$other — Chapter 6.13.

11. Exercises

Exercise 1 — collect three. Build a list of three values with three lappend calls, then print it and its length.

Exercise 2 — several at once. Do the same with a single lappend taking three arguments, one of which contains a space. Confirm the length is 3.

Exercise 3 — reproduce the bug. Build a list of filenames with set files "$files $f" where one name has a space. Print the length, then fix it with lappend.

Exercise 4 — append versus lappend. Append the same two-word value to two empty variables, one with each command. Print both values and both lengths, and explain.

Exercise 5 — collect into two lists. Loop over six names and sort them into a matched list and a skipped list using string match, reporting both counts.

Exercise 6 — the merge trap. With set a {1 2} and set b {3 4}, predict the length after lappend a $b. Then produce a four-element list instead.

12. Remember

  • lappend varname value ... adds elements to a list variable, in place. No $ on the name.
  • It is one of only two list commands that modify the variable — the other is lset.
  • It quotes each value as one element, so a value containing spaces stays one element.
  • It takes several values at once, creates a missing variable, and returns the new list.
  • set l "$l $v" is wrong before it is slow — it corrupts the element count and rebuilds the string every time.
  • Initialise with set l {} anyway, so a typo cannot start a second list.
  • append adds characters; lappend adds elements.
  • lappend l $otherlist adds one element. Use {*} to merge.

Next: inserting and removing elements anywhere in a list.

Where this fits

Part of the Tcl curriculum.