All except the most recent version of tcl (ver 8.0) are completely string based interpretive. The newest version includes some binary phases to increase speed. The language is procedure based, with all operations taking a list of string parameters. Even the built in tcl commands are approached in this fashion. The string parameters are handled in a list, with list operatives being built into the language. When dealing with C the items in the list become strings in the *argv array which is supplied to the procedure, in a similar fashion in which the operating system hands the command line parameters to the main() function of a program.
The list of parameters is interpreted before being passed to the procedure which is called. Any variables which are in the parameter list are replaced with their contents. This replacement is similar to "glob" replacement by a shell, where a "*.html" in a command is replaced by a list of all of the files ending in the ".html" extension.
Once a procedure has received its arguments, it processes and then returns. A numeric value is returned by most built in commands, with '1' indicating success and '0' indicating failure. Some of the more complex commands can also return string values.
Back to the top
Variables in tcl/tk are "declared" by setting them to a value. Each variable can be "set" multiple times, and exists within scope until "unset". When setting a variable all that is required is the variable name. When using the variable the name must be preceded by a "$".
A few quick notes to get you started: the comment symbol in tcl/tk is "#"
and it works up until the next end of line character. The selection of "#"
is rather convenient as it allows tclsh to ignore the line which is used by
UNIX to determine what shell to run. The "puts" command
takes a string and prints it to the screen. Now for your first tclsh program.
Not wanting to break with tradition, here is "hello world":
Now that we can put things to the screen, how about playing with some
variables. The following program uses the "set" operator to put the string
"world" in the variable "stuff". Notice that the "$stuff" is interpreted by
the "puts" command, and the contents are printed, not the word "stuff".
Back to the top
Everything seen so far has been dealing with text. There is a good reason for this, everything in tcl is text. This is not to say that numbers can not be handled, but to do so, tcl requires special commands. Numbers are strings with just numbers in them. A mix of both numbers and letters will most often result in tcl interpreting the string as a word.
The "set" and "unset" operators work just as they did above with strings
when dealing with numerics. The "incr" operator takes a variable and
increments it by a specified value. The following piece of code plays with
a variable called "number" to give you an example of the "incr" operator.
Tcl also handles negative numbers, scientific, hexadecimal, octal, and
floating point. The following code shows off all of these things:
Back to the top
The square and brace brackets have special meaning in tcl, and effect how the interpreter handles the string contained within. The brace brackets force no interpretation, and everything inside is passed to a command as it appears. There are numerous places where a programmer might not want interpretation to happen, and this will become more clear in the sections on procedures and controls.
The square brackets mean evaluation. In essence any string inside of the square brackets is treated as a tcl script and run by the interpreter. This parallels the back-quote in many shell programming languages.
A useful operation is the "expr" command, this is short for expression and
it returns the results of an equation contained in the string passed to it.
The combination of the square brackets and the "expr" operator allows
manipulation of variables. The following code sets a variable called
"number" to 3, and then sets a variable "stuff" to be 10 more than what is
contained within "number". Notice that the contents of "number" are not
The semi-colon character allows the programmer to issue multiple commands
on the same line. This becomes useful if we wish to put a couple of operations
inside of a set of square brackets. The following code outputs "hello world"
to the screen as well as the contents of "stuff".
The semi-colon is a neat trick, but it really isn't necessary. It is
perfectly legal to have end of line characters inside of square brackets. The
following code does the same thing as the above example.
Back to the top
What good is a programming language without being able to call procedures? Tcl supports the basic procedure stuff that you would expect, in fact all of the commands which have been looked at so far have just been procedures which are provided for you by the language. Calling a procedure is as simple as calling any of the commands, just give the name of the procedure plus any arguments you wish to pass it. The procedure must be defined before its first calling. Recursive procedures are supported.
The "proc" key-word is what allows you to define a procedure. After "proc"
you give the name of the procedure, the name of arguments and then the script
which is to be executed when the procedure is called. The arguments must
be there, even when you don't need any. There are a couple of ways of
dealing with this: give the name "args" and then ignore it, or use a
set of brace brackets. The script which is executed when the procedure is
called is also contained in brace brackets, this follows from the fact that
we do not want the contents interpreted during the definition of the procedure,
only during execution. The following code is a new twist on our familiar
Accessing the arguments passed to a routine can be done in two ways. If
you know how many arguments you want, then simply specify them inside of
brace brackets. The second method is using the key-word "args" instead of
an argument name, this puts all of the arguments in a variable called "args"
which can then be accessed as a string or list. The following example takes
exactly two arguments:
By using the "args" key-word in your argument list, you obtain a sort of
catch-all. All of the arguments that aren't taken up by variables before the
"args" are put into a variable called "args". This variable can be accessed
like any other.
The return value of a procedure is implicitly the return value of the last
statement in the script. If you wish to force leaving of a procedure early,
or return a specific value that isn't returned by some other line, use the
key-word "return". This works just like the return statement in C. A simple
procedure to add two numbers and return the sum is given below.
Back to the top
Strings in tcl/tk are a lot like those in C. We have already seen examples of variable substitution using the "$" operator, but this is not the only special character. As was mentioned in the introduction to variables the "\" character can precede a "$" to print a "$" and not have it interpreted as a special character. Tcl also provides a fairly standard array of "\" characters:
Everything in tcl is based on strings, so it is fitting that there be a
series of string manipulation routines. The string routines are all based
on a single command "string" which takes as its first parameter an indicator
of what you would like to do with the string. Features exist for finding the
length, ranges, and doing comparisons. The following code illustrates some
of these features
The "regexp" operator allows some of the rudimentary regular expression operations to be performed on a string. The typical regular expression operators are supported: ".", "^", "$", "\", "[...]", "(...)", "*", "+", "?", and "|". The "regexp" operator takes an argument for the expression to be evaluated and an argument for the string to be operated on. The "regexp" command returns a '1' or '0' indicating success and failure. Another command called "regsub" does the regular expression operations using substitution. For more information on either of these see the man pages.
Back to the top
Control flow in tcl/tk is performed using procedures. In most cases the control flow statement takes several scripts as arguments, some of the scripts being conditions for execution and some for the script to be executed if the condition is true.
The "if" statement takes two scripts as arguments, the first is the
condition, and the second is what is to be run if the condition is true. The
"if" statement can also be paired with "elsif" and "else" statements. The
following code shows an example
The "while" statement takes two scripts as arguments, the first is the
condition, and the second is the script that is executed multiple times
until the condition is no longer met. If the condition is not met in the
first place then the execute script is not run.
The "for" statement is unnecessary, as everything that can be done with a
"for" can be done with a "while". The "for" statement, builds in some of the
common things that happen in a "while" as a short-cut for the programmer. The
"for" statement behaves in a similar fashion to its C counterpart. This
command takes four scripts. The first script is where variables are
initialized, the second is the stopping condition, the third script is for
incrementing, and the last is the actual body of the loop.
The "foreach" statement is very useful when trying to process lists or parse.
This command takes three arguments, the first is a variable name, the second
is a string (or list), and the third is a script. For each item in the list
the third script gets executed. Upon each iteration of the loop the first
variable gets the next word in the list. The following code prints the
words "one", "two", and "three" on separate lines.
The "switch" statement is a shortcut for multiple if-elsif clauses, using
the same condition variable. The structure of the "switch" is a little
different from the other control statements. It also takes an argument and
a script, but the script has to contain a specific format. The following
code fragment should help to make this clear.
Back to the top
Tcl does not handle errors very well, the addition of the tk toolkit
actually makes the error handling even uglier. Typical response of tcl to
errors is to bail out. Tk is a little better in that it brings up an
exception window, but there is not much that can be done after that. In
the most frequent cases the error has been caused from a syntax or illegal
operation, and so forcing the exit of a program is almost expected, so why
the concern? A useful aspect of most scripting languages is an interface out
to the command line so that programs can be run from the operating system.
The problem arises in what these programs return. Many UNIX programs are not
very careful about their exit codes, and the meaning of the codes varies from
program to program. Unfortunately a non-zero error code is interpreted by
tcl as a fatal error. The "exec" command takes a string which is the
command to pass through to the operating system. The following example uses
the UNIX date program to print the date to the screen.
Back to the top