append appends values to the value stored in a variable.

See Also

More string functions.
Concatenate values.
Append a word to a list.


append varName ?value value value ...?


official reference


Appends each value to the value stored in the variable named by varName. If varName doesn't exist, it is given a value equal to the concatenation of all the value arguments. This command provides an efficient way to build up long variables incrementally. For example, append a $b is much more efficient than set a $a$b, if $a is long.

append is a string command. When working with lists, definitely use concat or lappend.

To assign the empty string to a variable if it doesn't already exist, leaving the current value alone otherwise:

append var {}


Building a string of comma-separated numbers piecemeal using a loop.

set var 0
for {set i 1} {$i <= 10} {incr i} {
    append var , $i
puts $var ;# -> 0,1,2,3,4,5,6,7,8,9,10


Is the result of appending one list to another a list?

EE, PYK: No. The result of an appending one list to another might happen to be a list, but there's no guarantee, and even if the result is a list, it might not be the list one expects:

set a [list a b c]
set b [list 1 2 3]
append a $b
puts $a ;# -> a b c1 2 3

The third word in this new list is not c, but c1. Does anyone know if there are cases where an append would result in something not a list?

Here's an example of such a case:

set l1 [list a {b c}]
set l2 [list {d e} f]
append l1 $l2
llength $l1 ;# -> list element in braces followed by "{d" instead of space

RS PYK: The intended functionality seems to me to be closer to concat. But if you wish to use append, just add an extra space to separate the parts, which always guarantees that the result is a list composed of the original lists:

append l1 { } $l2

AMG: For performance reasons, when concatenating the results of multiple substitutions or interspersing substitutions with literal text, it's better to give [append] many arguments than to give it a single value argument.

append var xxx$a$b$c    ;# Has to generate temporary string xxx$a$b$c
append var xxx $a $b $c ;# No temporary strings needed

AMG: Single-argument append works just like single-argument set: it returns the value of the named variable. This isn't normally useful, but it might come in handy if the {*} expansion operator is used to produce the argument list.

If the variable doesn't exist, append dies with the same error that set would in the same situation. This is the only time append will complain about the variable not existing, since it's normally a creative writer. If the variable exists but is an array, once again single-argument append gives the same error as set, complaining about its inability to "read" it, once again showing single-argument append and set to be identical. The rest of the time, the errors given by append complain about not being able to "set" the variable.

AMG, update: I feel this is a bug and is inconsistent with the documentation. It makes more sense to me that single-argument [append] create the variable with empty string as its initial value, same as append var {} described below.

foo: by traditional wisdom, append var, when var doesn't exist, is very likely to be a mistake, which should raise an error to alert the programmer. OTOH, the TIP #323: Do Nothing Gracefully revision has lead to many commands now accepting essentially meaningless argument lists (not a criticism). append var could be handled like those, but it still remains to decide how it should act:

  • no-op (like most of the changed commands -- does not assign to var)
  • equivalent to append var {} (as per AMG's suggestion, but not really in line with other changed commands)
  • equivalent to variable var (i.e. var is created but remains undefined -- probably not a good idea)

AMG: append can be used in a one-liner to initialize a variable's value to empty string if it doesn't exist.

append var {} 

In the above code, if $var doesn't exist, it is created and the value set to the empty string. If it does exist, its value will be left unchanged. According to tcl::unsupported::representation, no shimmering is induced.