Tcl has a notion of lists, but as with everything it is implemented through strings. A list is a string that contains words.
A simple list is just a space separated series of strings:
set a {one two three four five}
will set the variable a
to the list containing the five
strings shown. The empty list is denoted by an open and close curly bracket
pair with nothing in between: {}
.
For the Prolog programmer, there is much confusion between a Prolog implementation of lists and the Tcl implementation of lists. In Prolog we have a definite notion of the printed representation of a list: a list is a sequence of terms enclosed in square brackets (we ignore dot notation for now); a nested list is just another term.
In Tcl, however, a list is really just a string that conforms to a certain syntax: a string of space separated words. But in Tcl there is more than one way of generating such a string. For example,
set fred {a b c d}
sets fred
to
"a b c d"
as does
set fred "a b c d"
because {a b c d}
evaluates to the string a b c d
, which
has the correct syntax for a list. But what about nested lists?
Those are represented in the final list-string as being contained in
curly brackets. For example:
set fred {a b c {1 2 3} e f}
results in fred
having the value
"a b c {1 2 3} e f"
The outer curly brackets from the set
command have disappeared,
which causes confusion. The curly brackets within a list denote a nested
list, but there are no curly brackets at the top-level of the list. (We
can't help thinking that life would have been easier if the creators of
Tcl would have chosen a consistent representation for lists, as Prolog
and LISP do.)
So remember: a list is really a string with a certain syntax, space separated items or words; a nested list is surrounded by curly brackets.
There are a dozen commands that operate on lists.
concat ?list list ...?
This makes a list out of a series of lists by concatenating its argument lists together. The return result is the list resulting from the concatenation.
lindex list index
returns the index-th element of the list. The first element of a list has an index of 0.
linsert list index value ?value ...?
returns a new list in which the value arguments have been inserted in turn before the index-th element of list.
list ?value value ...?
returns a list where each element is one of the value arguments.
llength list
returns the number of elements in list list.
lrange list first last
returns a slice of a list consisting of the elements of the list list from index first until index last.
lreplace list first last ?value ... value?
returns a copy of list list but with the elements between indices first and last replaced with a list formed from the value arguments.
lsearch ?-exact? ?-glob? ?-regexp? list pattern
returns the index of the first element in the list that matches the
given pattern. The type of matching done depends on which of the switch
is present -exact
, -glob
, -regexp
, is
present. Default is -glob
.
lsort ?-ascii? ?-integer? ?-real? ?-command command? ?-increasing? ?-decreasing{? list
returns a list, which is the original list list sorted by the chosen
technique. If none of the switches supplies the intended sorting technique
then the user can provide one through the -command
command switch.
There are also two useful commands for converting between lists and strings:
join list ?joinString?
which concatenates the elements of the list together, with the separator joinString between them, and returns the resulting string. This can be used to construct filenames; for example:
set a {{} usr local bin} set filename [join $a /]
results in the variable filename
having the value /usr/local/bin
.
The reverse of the join
command is the split
command:
split string ?splitChars?
which takes the string string and splits it into string on splitChars boundaries and returns a list with the strings as elements. An example is splitting a filename into its constituent parts:
set a [split /usr/local/src /]
gives a
the value {{} usr local src}
, a list.