##### 40.2.3.4 Lists

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.