TCLWISE
An introduction to the Tcl programming language
Sponsored Project: The Jim interpreter A small footprint implementation of Tcl |
Send a comment to the author
|
4. LISTS
4.1 Tcl list In Tcl everything is represented as a string. Lists don't escape
this fundamental rule of the language, instead the string representation
of lists is very direct to think for humans. The simplest form of
Tcl list is a string with zero or more space-separated words.
For example the string "a b c" is a three-element list, you can test
it using the llength command, it gets as argument a
Tcl list, and returns the number of elements present in such a list:
The empty list is represented by an empty string, that's "" or {}.
There is also a command that extracts a given element from a list
called lindex:
As you can see, lists indexes are zero-based. The first element is at index
0 ("a" in our example), the second is at index 1, and so on.
Lindex, and generally every list-related command that takes
a list index as argument accepts also "end" as index, that is used to
specify the last element of the list. There is also the form "end-<number>",
that referes to the last-<number> element of the list. Some example:
You may wonder how it's possible to create a list containing elements
that have spaces inside. The solution was already shown actually, and
is called grouping:
But when you need to write complex lists, the way to go is to use
a command that was created just for this, that's the list command:
List creates a list using every input argument as an element of the
list. We can create every kind of list with it, and of course nested
ones:
As you can see the lindex command can be used to directly access
nested lists. "lindex $mylist 2 2" means access the second element,
of the second element, of the list in $mylist.
4.2 The foreach command Foreach is a very powerful command used to execute a Tcl scripts
for every element of one or more lists. The command signature in
its simplest usage is:
foreach varname list script The following is an example to print the square of the first five
natural numbers on the screen.
For every element of the list, foreach assign its value to the specified
variable and execute the script. Actually instead of a single variable
the user may provide a list of variables, like in the following example:
This program will output:
Basically when the user passes a list of N variables, for every
iteration N new elements of the list are consumed to be assigned
to the specified variables, and the script is executed. Foreach
can do a bit more, accepting more than a variables/list pair
like in the following example:
This time the output will be:
It's the simple usage but with multiple lists walked in parallel.
As you can see foreach is a very flexible command for a data
structure that's central in Tcl, so you will see this command used
in almost every non trivial Tcl program.
4.3 The lrange command Lrange extracts a sublist from a list. The sublist to extract
is specified by a start and end index, indexes are as usually zero-based,
and it's possible to use the "end-<integer>" notation. Example:
4.4 The lappend command At this point we know a few commands that operate on lists:
llength, lindex, foreach, lrange. They have something in common
because all take a Tcl list as input. the lappend command instead
takes as its first argument the name of a variable containing a list, and
a variable number of other arguments. Lappend get the list stored in
the specified variable, append every other argument to the list
(every argument as a new list element), and set the variable to the value of
the new obtained list. The value of the list obtained is also returned
as lappend's return value:
If the specified variable does not exists, it will be created
(and lappend will assume the previous content was the empty list).
With lappend we are able to create a user defined procedure that
given an input list, returns a list composed of the same elements in
reversed order. A good name for such a procedure is lreverse, and it is
very simple to write:
The usage is simple too:
In the lreverse implementation there are two core commands that we
never used. The first in order of apparition is incr, the second
is while. Incr is very simple, it takes two arguments: the name
of a variable, and an integer. It gets the value of the variable
that must be an integer number, add the second argument to it, and
set the result as the new value for the variable.
If the variable a is set to 6, the command "incr a 2" will set it
to 8, while "incr a -1" will set it to 5, and so on.
The second argument, while, takes two arguments, the first is
an expression, the second a script. The script is executed while the
expression continues to be true. The expression, like it happens for
the if command, is evaluated using the expr command internally.
4.5 The lset command The lset command is in some way the complement to lindex.
While lindex returns the list element at the specified index,
lset replaces the list element at the specified position with
a new value. Like lappend, lset takes as input a variable
name containing a list, and directly modify the value of the variable
instead to just return a modified list.
An example of the lset usage:
Lset can directly access nested lists in a similar fashion to
lindex, specifing multiple indexes, so for example the command
"lset foobar 2 3 $newval" Will set $newvalue as third element
of the list that's the second element of the list contained inside
the variable $foobar.
4.6 The lsort command As suggested by the name, the lsort takes a list in input, and
returns it sorted as return value. The command structure is:
lsort ?options? list Note that in Tcl it is well accepted to show the command structure
surrounding with two question marks the argument(s) that may be
omitted in the actual command usage (practically this means that
the lsort command can be called with just an argument: the list).
Options are just strings with a special meaning for the lsort command,
and are prefixed with a "-" character as it's usual with Tcl commands
(but note that lsort knows that all the options except the last
are arguments). The goal of options is to modify the way lsort sorts,
and can be combined to get specific effects. Not all the options
will be exaplained here, please check the manual page if you want
the details.
Some example:
The first example calls lsort without options, but just with
the list to sort: if invoked in this way lsort sorts the list
comparing using ASCII value of letters (actually unicode
is used, but for now you can ignore this expecially if you are
not using unicode strings).
The second example adds the -decreasing option to reverse
the sorting order. The third example changes the comparison algorithm
specifing the -dictionary option: this mode is smarter for many
uses as it ignore the case of the letters and is able to deal better
with numbers (if a string contain a number, the value of the number
is compared by value). The effect is similar to the order of
lemmas in a dictionary, thus the name.
An interesting use of lsort is due to the -unique option
that returns every element only one time if it's repeated:
It may be comfortable to include this functionality in a library
directly as a Tcl procedure called unique. The implementation
is simple:
4.7 List values against variable names Maybe it's just too early to ask complex questions about Tcl, but
some reader may wonder why there are Tcl list commands working in a
functional way, that's operating directly
on the value of the list to return another list as result, and
commands that instead takes the name of a variable where a list is stored.
For now it's enough to know that there are efficiency reasons
because one approach is more convenient than the other. The second
reason is that actually it is more common to use lset and lappend
against lists already stored in variables.
Of course, as it's the norm with Tcl, if you need to have similar
procedures operating with values you are free to implement they. Actually
there are already procedures that can be used for the scope,
that are lreplace and concat. If you are interested take
a look to the manual pages of this functions. Just as example the following
is a function similar to lset, that takes as arguments a list, an index,
and a new value, and returns a list where the specified index is replaced
with the new value:
It's written in terms of lset, because lset already returns the value
of the modified list. The usage is simple:
Note that mylset will not alter in any way the list passed as argument.
In Tcl, procedure's arguments are local variables, and arguments are
passed by value. Note how mylset will not alter the list stored
into the a variable:
The a variable continues to contain the list a b c d, Tcl is a safe
language, it is not possible to alter the value of a variable passed
as argument unless the procedure is written in a special way, but
in such a case the user must pass the name of the variable, and not
it's value substituted using the $ character before the variable name.
We will see all this things better later.
|
Other Tcl/Tk books Index
2.1 Anatomy of a command
2.2 Grouping
2.3 Program structure
2.4 Substitution of commands
2.5 Substitution of variables
2.6 More on interpolation
2.7 Comments
2.8 That's it
3.1 User defined procedures
3.2 The if command
4.1 Tcl list
4.2 The foreach command
4.3 The lrange command
4.4 The lappend command
4.5 The lset command
4.6 The lsort command
4.7 List values against variable names
5.1 The append command
5.2 The string command
5.3 string range
5.4 string index
5.5 string equal
5.6 string compare
5.7 string match
5.8 string map
5.9 string is
5.10 More string subcommands
5.11 Advanced string matching
6.1 Converting strings to lists
6.2 From strings to list of chars
6.3 Converting lists to strings
6.4 Manipulating strings as lists
7.1 Local variables
7.2 Top level
7.3 Global variables
7.4 Procedures arguments and pass by value
7.5 Procedures with a variable number of arguments
7.6 Procedures with default arguments
7.7 Recursion
7.8 Recursion limit
8.1 The switch command
8.2 The for command
8.3 break and continue
8.4 The lack of goto
9.1 Programs executing programs: the eval command
9.2 Breaking the rules with uplevel
9.3 Passing variable names to procedures
9.4 Mapping scripts to lists
9.5 The rename command
9.6 Expanding lists into arguments in Tcl 8.5
Additional 20 chapters in the printed version.
Related man pages
Links
Author HomeTclers Wiki |
Copyright © 2004 Salvatore Sanfilippo. All rights reserved. This online book is for personal use only. It cannot be copied to other web sites or further distributed in any form. |