A paper presented to:  DAVID HANSEN  In partial fulfillment of the requirements for the course:  STRUCTURES OF PROGRAMMING LANGUAGES  (CSIS 420) 

ZACHARY HAYES  November 29, 2006


1.0  Introduction­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 1  2.0  Historical Background ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 1  3.0  Syntactic Structure ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 2  3.1  Words ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 2  3.2  Commands ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 3  3.3  Evaluation ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 3  3.4  Substitution ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 4  3.4.1  Backslash Substitution ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 4  3.4.2  Command Substitution ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 4  3.4.3  Variable Substitution­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 5  3.4.4  Order of Substitution­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 5  3.4.5  Substitution and Word Boundaries­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 5  3.5  Double Quotes ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 6  3.6  Braces ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 6  3.7  Comments ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 6  4.0  Variables­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 7  4.1  Basic Variables ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 7  4.2 Abstract Data Types ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 8  4.2.1 Arrays ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 8  4.2.2 Lists ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 9  5.0  Flow of Control­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 9  5.1  Eval Command ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 10  6.0  Sub­Programming ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 10  7.0  Personal Experience ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 11  Appendix A: Example Tcl Code ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­A1  A.1.1: n!­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­A1  A.2.1 Structured Information Sorter­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­A2  A.3.1 Random Text Generator ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­A3

ABSTRACT  Tcl was developed by John Ousterhout in the early 1980’s.  He never expected it to grow  as much as it has. Tcl continues to attract more uses each year and has received the ACM  Software System Award for "a software system that has had a lasting influence". Being  an embeddable language Tcl has many new extensions continually coming out every  year.  However no one can replace the easy to learn, general package, of Tcl.  Tcl has all  that you would need to develop full blown applications.  Over the course of the paper I  will provide a brief look into Tcl /Tk with an emphasis in Tcl so that we may understand  the phenomenon that is Tcl.

1  1.0 Introduction  Have you ever been so frustrated with your own, poorly written, code? If so did  you develop your own language based off that aggravation? Tcl, pronounced “tickle,”  was originally born out of frustration by programmers devising their own “poorly  1  written” languages intended to be embedded into applications.  Tcl is a very simple  scripting language that can be picked up in a matter of hours by anyone familiar with  programming. Tcl (Tool Command Language) received its name based on its intended  2  usage as an embeddable command language.  3  Tcl is considered a weak functional language.  This is because TCL has many  features that could be considered imperative.  With the right extensions, one could easily  make it object oriented, or even logical, if the extension were written.  Tcl has higher­  order functions and functional abstractions built into the language; however, Tcl is not  widely used in this manner.  Tcl started out as an experiment because someone was  4  embarrassed by his code.  Tcl has many similarities to LISP, C, and the UNIX shell.  2.0 Historical Background  Professor John Ousterhout at the University of California at Berkley wrote Tcl in  the early 1980’s.  The idea for Tcl grew out of Ousterhout’s work designing tools for  integrated circuits.  At that time, there was not much invested in the command languages  used during development; most were weak, quirky, non­reusable languages.  Every tool  ended up with its own uniquely written command language, which Ousterhout found  5  embarrassing.  In 1987, Ousterhout got the idea for an embeddable command language.  Thus  began his work to create an interpreted language with library packages that could be  reused for many different applications; he also envisioned generic facilities, such as  variables, procedures and control structures.  As Ousterhout explains: 
The notion of embeddability is one of the most unique aspects of Tcl, and it led me to the  following three overall goals for the language:  1)  The language must be extensible: it must be very easy for each application to add its  own features to the basic features of the language, and the application­specific  features should appear natural, as if they had been designed into the language from  the start.  2)  The language must be very simple and generic, so that it can work easily with many  different applications and so that it doesn’t restrict the features that applications can  provide.  3)  Since most of the interesting functions will come from the application, the primary  purpose of the language or to integrate or “glue together” the extensions.  Thus the  6  language must have good facilities for integration. 

John Ousterhout Tcl Developer X­change “History of Tcl” October 2005, 28 October 2006, ActiveState  2  Ibid.  3 “Tcl Heritage” 16 July 2006. 28 October 2006  4  Ibid.  5  Ousterhout  6  Ousterhout

2  After Ousterhout stopped working on designing tools, Tcl became a personal academic  experiment.  Little did he know how well it would expand.  In 1990 Tcl became open to the public after Ousterhout presented a paper on Tcl  at the UNENIX Conference and found many people were interested in getting a copy of  Tcl.  Shortly after the conference he began working on Tk, a graphical user interface  extension to Tcl, which was also available to the public.  From 1989 to 1993, Tcl/Tk  popularity grew an order of magnitude each year, expanding a dozen users to several tens  of thousands by 1993.  This growth was due to the fact that Tk was the easiest way to  create graphic user interfaces in UNIX (which at the time was the only thing Tcl/Tk ran  7  on) and also because of Tcl’s embeddable nature.  A good portion of development on Tcl actually took place in 1994 when  Ousterhout left his position at Berkeley and began working for Sun Microsystems in  order to make Tcl a universal scripting language for the Internet.  In 2005, Ousterhout  recalled some of the advancements made during his time at Sun: 
The additional resources provided by Sun allowed us to make major improvements to Tcl  and Tk. Scot Stanton and Ray Johnson ported Tcl and Tk to Windows and the Macintosh,  so that Tcl became an outstanding cross­platform development environment; today, more  than two­thirds of Tcl downloads are for Windows. Jacob Levy and Scott Stanton  overhauled the I/O system and added socket support, so that Tcl could easily be used for  a variety of network application.  Brian Lewis built a bytecode compiler for Tcl scripts,  which provide speedups of as much as a factor of 10x.  Jacob Levy implemented Safe­Tcl,  a powerful security model that allows untrusted scripts to be evaluated safely.  We added  many other smaller improvements, such as dynamic loading, namespaces, time and date  support, binary I/O, additional file manipulation commands and an improved font  8  mechanism. 

In 1998, Ousterhout left Sun and started his own business called Scriptics to focus  entirely on Tcl; within a month, half of the Sun Tcl team had joined him and began  development on TclPro, a retail version of Tcl.  In the spring of 1998, Tcl won the ACM  Software System Award; awarded each year for a software system that has had a lasting  9  influence.  3.0 Syntactic Structure  There are eleven important rules that define the syntax of the Tcl language.  These  eleven rules define the core of the language, if one masters these rules; he is on the way  to mastering Tcl.  The purpose of these rules is to help the programmer understand how  the language works, variable declaration, control structures, and processes.  3.1 Words 

John Ousterhout Tcl Developer X­change “History of Tcl”, October 2005. 28 October 2006, ActiveState.  8  Ibid.  9  Ibid.

3  Tcl code consists of Strings; each word in the String is called a “word.”  Words of  a command are separated by white space, with the exception of newlines which indicate  10  the conclusion of a command.  Each word may have an arbitrary string value, and the  11  white space is not part of the word unless quoted.  Aword  “This is a word”  Multiple words  3.2 Commands  Everything in Tcl is a string containing commands.  Each command consists of  one or more words with the first word being the name of the command, and each  additional word being the arguments to the command.  Commands are separated by  semicolons and newlines unless the String is quoted.  3.3 Evaluation 
12  Tcl evaluates command in a two­step process, parsing and execution.  In the  parsing step Tcl interprets the syntactic rules and divides every command into words and  perform substitutions.  Every command is parsed in exactly the same way; during the  process the interpreter does not give any meaning to the value of the words.  The parser  simply replaces variables, such as $a; however the interpreter does not know or care  what the variable is.  The execution step of the evaluation assigns meaning to the words.  As stated  above, the first word in a command is the name of the command being executed.  During  the execution step the interpreter checks to see if a command by that name is defined.  Tcl invokes a command, passing each additional word to the command procedure.  Then  the procedure interprets the words as it pleases. This process is shown in figure 1. 


Develop Connection “Tcl(n): Tcl Built­In Commands,” November 6, 2006  11  John Ousterhout, Tcl and Tk Toolkit (Partial Draft). Addison­Wesley Publishing Company, Inc 1993, 26  12  Ibid. 26

13  Figure 3.1 Tcl command evaluation. 

3.4 Substitution  One of the most important aspects of Tcl is substitution.  There are three types of  substitutions: backslash substitution, command substitution, and variable substitution.  Substitution simply replaces some word with some other value.  Substitution can occur at  any point in a command, including the name of the command; there can be an arbitrary  14  number of substitutions within a single word or command.  3.4.1  Backslash Substitution  Backslash (‘\’) substitution in Tcl is exactly like how Java/C­type languages  handle substitution.  In most cases, the symbol following the backslash will appear as an  ordinary character in a word.  For example “\{“ appears as a literal “{“ in the word.  There is nothing special about this type of substitution: it is mainly used for formatting  words, e.g., when printing a dollar amount “\$” would be used for a $ to literally appear.  3.4.2  Command Substitution  Command substitution causes a command to be executed by another command.  set x [expr 1 + 3] 

13  14 

Ibid 27  Ibid 28

5  Is an example of this; the first command sets a variable x to the result of the expression  [expr 1 + 3].  Any character between the brackets ([ ]) must constitute a valid Tcl  command.  Command substitutions may appear anywhere in a word and there may be  15  more than one substitution in a single word.  The substitution of commands is done  16  recursively by the Tcl interpreter.  An example of this can be found in the Random Text  Generator discussed in Appendix A.3.  3.4.3  Variable Substitution  Words that have a leading dollar sign (‘$’) are interpreted as variable after the set  command has been issued.  set a 3; puts “$a”  Sets the variable ‘a’ to 3 and prints it out.  Notice in the print statement how the ‘a’ has a  leading $, therefore it replaces $a with 3 and prints 3.  Similar to command substitution,  variable substitution may appear anywhere in a word, and there may be more than one  17  substitution in a single word.  3.4.4  Order of Substitution  Substitution can be confusing if one is not used to it.  However,  Ousterhout discusses two rules that explain how substitution is performed: 
A typical scenario is for a users to be surprised at the behavior of a script because a  substitution didn’t occur when the user expected it to happen, or a substitution occurred  when it wasn’t expected.  However, I think you’ll find Tcl’s substitution mechanism to be  simple and predictable if you just remember two related rules:  1. Tcl parses a command and makes substitutions in a single pass from left to  right.  Each character is scanned exactly once.  2. At most, a single layer of substitution occurs for each character; the result of  one substitution is not scanned for further substitution.  Tcl substitutions are simpler and more regular than you may be used to if you’ve  18  programmed with UNIX shells (particularly csh) 

So each substitution occurs left­to­right and each one is evaluated before continuing. For  example:  set y [set x 0][incr x][incr x]  (Note: incr. increases value of x by 1.) This example will always set the variable ‘y’ to  19  the value 012.  This tells us a lot about the language and its scope.  3.4.5  Substitution and Word Boundaries 

Ibid. 29  Developer Connection “Tcl(n): Tcl Built­In Commands” November 6, 2006  17  Ibid.  18  John Ousterhout, Tcl and the Tk Toolkit (Partial Draft) Addison­Wesley Publishing Company, Inc 1993,  34.  19  Developer Connection “Tcl(n): Tcl Built­In Commands” November 6,2006

Substitutions do not affect the word boundaries of a command. During the  substitution process, the value that is being substituted becomes part of the word it is next  to, even if the substitution contains special characters, such as white space. 20  3.5 Double Quotes  There are times when a programmer wants a word to contain white space, e.g.  when trying to set a variable to a string of words.  This is accomplished by placing double  quotes around the words.  Double quotes are not the only way to do this; it is important to  recognize this since there are different interpretations depending on how words are  connected, either with double quotes or with braces.  If the first character of a word is a double quote (“) then the word is terminated by  the next double quote character.  If any special character appears in between the two  double quotes (semi­colons, closing brackets, white space, etc).  It is treated as any other  ordinary characters and literally included in the word.  All three types of Tcl substitution  21  also take place while in between double quotes.  3.6 Braces  The alternative to double quotes is the brace (‘{‘).  Similar to double quotes, the  word will terminate by the matching closing brace.  Unlike the double quotes, braces may  be nested.  The main difference between the double quote and the brace lies with  substitution.  No substitutions are performed on any characters in the word when using  braces.  Everything loses its special interpretation while in the braces, meaning the word  22  typed between the braces is the literal word you get.  Braces are usually only used in  special cases, such as the use of the eval command.  3.7 Comments  A comment always begins with a hash mark (#) at the beginning of a line; note  that the beginning of a line follows a new line character or a semicolon.  The hash mark  must be the very first non­blank character on the line.  This is very similar to how  comments are done in languages such as Python except that comments must be on a new  23  empty line.  An interesting side effect of comments is if you have special characters inside a  comment, the interpreter will not always behave as expected, thinking the special  character is not inside of a comment.  It is preferred to put comments in a particular form:  # [this is a comment] 

20  21 

Ibid.  Ibid.  22  Ibid.  23  John Ousterhout, Tcl and Tk Toolkit (Partial Draft) Addison­Wesley Publishing Company Inc. 1993, 33

7  The reason for this is to eliminate problems caused by a special character within the  comment.  4.0 Variables  It is not uncommon for people to call Tcl and a string oriented language, and for  good reason.  In Tcl, every single data type is a string on the Command String layer; this  24  includes: numbers, characters, lists, code, and dictionaries.  The interpreter reads these  strings and depending on what kind of command is being executed, it interprets the string  as a different type, such as an integer.  Even though there is only one data type in Tcl  there are two different kinds of variables: basic variables, such as traditional strings, and  25  arrays and lists.  4.1 Basic Variables  Basic variables are very simple; they consist of only two things, a name and a  value.  Both things can be arbitrary strings.  Some examples of variable names and  variable values are:  “This is a Variable”  !@#  22  All of these are treated as strings and any of them could be the variable name or  26  variable value.  There are few constraints on either the variable name or variable value.  This means the variable names may be as long as one likes and may contain nearly any  character; an exception is that variables can not start with ‘{‘, unless the variable name is  enclosed in quotes.  To access a variable with a unique name, the $ is placed in front of  the variable name.  Like JavaScript or PHP, Tcl has dynamic type binding; this permits  the programmer to not specify the type when declaring a variable.  Tcl uses the command set to create, read, and modify variables.  The set  command takes one or two parameters, each yield a different result.  The first argument is  always the name of the variable.  The second argument is an optional value for the  variable.  If no second argument is given, set reads the variable and returns the value it  holds, if any.  This is a key command to Tcl that is often used.  Here is an example of the  set command:  set a {Eggs: $2.18/dozen}  >> Eggs: $2.18/dozen  set a  >> Eggs: $2.18/dozen  set a 44 

Salvatore Sanfilippo Tcl Wise: Guide to the Tcl Programming Language (Pre­Release)  25  John Ousterhout, Tcl and Tk Toolkit (Partial Draft) Addison­Wesley Publishing Company Inc. 1993, 37  26  Ibid. 37

8  >> 44  In the above sample, the code sets ‘a’ to the string “Eggs: $2.18/dozen”, then reads the  27  value of ‘a’ and finally modifies the value, changing it to the string “44”.  Tcl variables can represent anything: numbers, list, scripts, etc.; however, they are  always stored as strings.  Tcl is a type­less language, so there is no need to declare the  28  variables before setting them.  This makes Tcl variables very easy to understand,  because variable interpretation is done under the covers by Tcl.  4.2 Abstract Data Types  Tcl has two abstract data types, the Array and the List.  These two abstract data  types are at the very core of the language, allowing the programmer to keep collections of  strings in a certain format and use them in their respective ways.  4.2.1 Arrays  The Array is a collection of elements with a name and a value.  The name of an  array element also has two parts, the name of the array and the name of the element  within the array.  Similar to basic variable array names and element names, the value may  be any arbitrary string.  Many programmers associate the Tcl array with an associative  29  array, hash map, or dictionary which often appears in other languages.  Similar to the  basic variable, you use the command set to assign a value to the array:  array set “capital(New Mexico)” “Santa Fe”  >> Santa Fe  As expected, you may think this is exactly the same as a basic variable,  the variable  name is “capital(New Mexico)” and the variable value is “Santa Fe” and you would be  absolutely correct.  The difference between the two is the commands that can be used on  the variable.  For example there is a copy function that can be applied to arrays:  array set B [array get A]  Means get the array A and set it to B.  This is just one of the many helpful commands that  30  are associated with arrays.  Arrays are singularly dimensioned; however, there is a way to represent arrays as  multi­dimensioned.  The idea behind this is to create an array and set the name of the  element to:  set “matrix(index1,index2)” 

27  28 

John Ousterhout, Tcl and Tk Toolkit (Partial Draft) Addison­Wesley Publishing Company Inc. 1993, 37  Ibid. 38  29  Ibid. 39  30 “Tcl Heritage” 16 July 2006. 28 October 2006

31  This is actually an array with the key being “index1,index2”. 

4.2.2 Lists  The other type of structure is the list, which is simply a collection of strings.  This  allows the user to collect any number of values in a single location.  Lists are represented  as strings with special structures, so one can store lists into a variable, nest them into  another list, and even type them to commands.  In other words, a list is simply a string  separated by spaces or tabs.  set myList [list this is hello world]  >> this is hello world  lsort myList  >> hello is this world.  There are many special features that can be only performed on lists, such as sorting,  32  getting the length, or getting a certain element with the list.  Unlike most traditional list  we can access them by index with the lindex command, for example:  lindex “this is a list” 1  >> is  lindex “this is a list” end  >> list  The above example grabs an element from a list.  Notice that list can be set to a variable  or indexed on the fly.  Also, indexing starts at zero, similar to languages such as Java.  We also have a keyword, “end,” which is the index to the end of the list.  The Tcl list has  many unique commands built in, making lists very powerful tools.  5.0 Flow of Control  The flow of control statements in Tcl are very similar to the control structures found  in C programming language and command line languages like csh.  These statements  include, if, while, for, foreach, switch, and eval.  The major difference is that each one is  a command that takes a different number and type of arguments.  if {cond_1} {script_1} elseif {cond_2} {script_2} else  {script_3}  This is an example of the if command in Tcl, which takes an arbitrary number of  arguments (words) that are parsed in a way that control flow similar to the if statement in  C.  Similar to the looping commands, they are commands and take arguments which the  Tcl interpreter parser breaks up and executes like their C counterparts. 

31  32 

John Ousterhout, Tcl and Tk Toolkit (Partial Draft) Addison­Wesley Publishing Company Inc. 1993, 41  Ibid. 51­52

10  5.1 Eval Command  One of the more unique control structures is the eval command.  The purpose of  the eval command is for creating and executing Tcl scripts on the fly.  A Tcl script is  multiple Tcl commands put together.  The most important use of eval is to force another  level of parsing.  As mentioned earlier, Tcl parses and substitutes only once; however  with the eval command multiple levels of parsing can be achieved.  Suppose one wanted  to remove a list of variables:  set myList [list varA varB ...]  foreach I $myList {unset $i}  becomes:  set myList [list varA varB ...]  eval unset $myList  with the eval command a command can be executed over an entire list, if set up  33  properly.  Many Tcl’ers (a nickname for those that use Tcl) think that this is a dangerous  or bad practice because of its double substitution; however, it does simplify some  34  operations in the language.  6.0 Sub­Programming  Most usable Tcl programs use procedures.  Procedures provide a quick and easy way  to prototype new features in applications.  Tcl procedures make for easy reuse.  Procedures are similar to methods or functions as seen in other languages, with similar  syntax as Java.  proc name {argList} {script}  Often times Tcler’s will rewrite procedures that run often in C to increase the  performance of the given procedure.  Custom made procedures with the eval command  make a very powerful combination.  The scope of a variable inside of a procedure is always local to the procedure  including the arguments that are passed into the procedure, which means the value must  be returned for the value to leave the procedure.  This can be done in two ways, explicitly  with the command return, or implicitly by defaulting to the result of the last line executed  in the procedure.  There are many unique things that a programmer can do with procedures and also  many exceptions to the scoping of procedures.  For example, one can create a global  variable with the keyword “global”, but you must type “global varName in any procedure  that will know of the value.  Other keywords include: upvar or uplevel, which are used 

John Ousterhout, Tcl and Tk Toolkit (Partial Draft) Addison­Wesley Publishing Company Inc. 1993, 67­  68  34 “Tcl Heritage” 16 July 2006.  28 October 2006

11  for accessing variables outside of the scope of the procedure.  These keywords can be  35  used for writing custom control structures.  7.0 Personal Experience  Tcl is an amazingly easy language to learn and develop software with, even more so  then Python, which is often considered an easy language.  Over the course of three  months, I have learned a lot more about programming through writing some very simple  programs in Tcl.  I have enjoyed learning Tcl more than any other programming language  because of its simplicity, and how easy it was to learn and understand commands.  One of the more interesting things I learned about the language is that it is very  expandable and easy to change the use statements to better fit my individual style.  For  example, if I do not like the “if” keyword for an 'if' control structure in Tcl, I can change  it to the “hi” keyword by:  rename if hi  So, a programmer would be able to make the syntax more understandable to the user.  This can be very good for writability but by doing so you sacrifice readability making it  nearly impossible for others to read.  Although it is very neat, I would suggest sticking to  the command names that are built into the language.  Active Tcl, the distribution I used, has a built­in Tcl interpreter for the Linux  command line.  This allows users to execute Tcl commands on the fly from the command  line, making testing things in Tcl very simple.  However it is not the only way to execute  a Tcl program; the command­line interpreter has an optional argument, which is a name  of a Tcl file that you want to execute.  These are done using the tclsh <filename.tcl> in  the Linux command line.  There are Windows distributions of Tcl; however, for my  experience I stuck to Linux.  Tcl is an incredible language whose popularity has grown dramatically ever since  its release.  I have only scratched the surface of all the language can do.  I would  encourage anyone who is interested to advance their knowledge of Tcl/Tk, for you may  see it in your future work place. 


John Ousterhout, Tcl and Tk Toolkit (Partial Draft) Addison­Wesley Publishing Company Inc. 1993, 69­  75


Appendix A: Example Tcl Code 
The following are some basic example of what code looks like in Tcl, using some  very basic problems. Tcl code can be written on a single line if one wishes however for  clarity I will try to break it up the best I can so you can clearly see some of the amazing  features of Tcl. 

A.1.1: n! 
Problem: A recursive factorial program that accepts a single integer n as input and  outputs n! Input is passed to the program as a command­line parameter.  A.1.2 Solution 
###################################################  # A procedure that find the factorial of a number  #  # INPUT: n, the number we are getting the factorial for  # OUTPUT: the factorial of n  ###################################################  proc fact n {  #if they put a negative number no  #solution exist  if { $n < 0 } { return "Non­Existent" }  #check if the number is the base case,1.  if { $n == 1 || $n == 0 } {return 1}  #call itself recursively multiplying the solution by  #the current number  return [expr $n * [fact [expr $n­1]]]  }  #check if the user gave an argument via command line  #if not: print a usage statement  #otherwise: get the factorial of the number  if {$argc != 1} {  #prints a usage statement to the console  puts "Usage: tclsh fractorial.tcl \$num"  } else {  #set the number to the user inputted value  set num [expr [lindex $argv 0]]  #print out to the console what the factorial of  # n is.  puts "The factorial of $num is [fact $num]"  } 

A.1.3 Sample Inputs 
$ tclsh factorial.tcl  $ tclsh factorial.tcl 5  $ tclsh factorial.tcl ­5


A.1.4 Sample Outputs 
Usage: tclsh fractorial.tcl $num  The factorial of 5 is 120  The factorial of ­5 is Non­Existent 

A.2.1 Structured Information Sorter 
Problem: A program that keeps track of information about Persons. A Person  has a  “character string” attribute called name  and an “integer” attribute called age. The  program should reads a comma­delimited name/age pairs from a file and populate the  program with a collection of Persons. It then sort the set by name, outputting the name  of  each Person  in sorted order, and output the average age of all the Persons.  A.2.2 Solution 
#create a list of people  set people [list]  #initialize variables  set ageSum 0  set averageAge 0  set size 0  #Constants  set _NAME 0  set _AGE 1  #Check that a file was given  #if not: print usage statement  if {$argc != 1} {  puts "Usage: tclsh db.tcl \$filename"  } else {  #check to see if the file given exist,  #if not: print "file does not exist"  if {[file exists [lindex $argv 0]]} {  #open a file (file name that is given)  set filename [lindex $argv 0]  set infile [open $filename r]  #go through the file reading each line.  while { [gets $infile line] >=0 } {  #for each line trim all leading and trailing white  #space and then split the line at the ','s  and  #add the data to the people list  lappend people [split [string trim $line " "] ',']  }  #make a copy of people that is sorted (sort the people by name)  set sortedPeople [lsort ­index $_NAME $people]  #get the size of the list (# of people in list)  set size [llength $sortedPeople]


#add up all the peoples ages  for {set i 0} {$i < $size} {incr i} {  set ageSum [expr $ageSum + [lindex [lindex $sortedPeople $i]  $_AGE]]  }  #get the averageAve  #Note: * 1.0 on the bottom makes it not round  set averageAge [expr ($ageSum) / ($size * 1.0)]  #print out the names of the people in the list  puts "PEOPLE IN LIST"  puts "­­­­­­­­­­­­­­­­­­­­­­­­­­­­­"  for {set i 0} {$i < $size} {incr i} {  puts [lindex [lindex $sortedPeople $i] $_NAME]  }  #print the average Age of the People in my Collection  puts "The average age of the people in the list is: $averageAge"  } else {  #no file exist let user know  puts "No such file exists"  }  } 

A.2.3 Sample Input File 
Hansen,7  Smith,82  Flintstone,23  Schlablotnik,39  Doe,45  Smith,19  Jones,34 

A.2.4 Sample Output File 
PEOPLE IN LIST  ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­  Doe  Flintstone  Hansen  Jones  Schlablotnik  Smith  Smith  The average age of the people in the list is: 35.5714285714 

A.3.1 Random Text Generator  Problem: use grammars to generate somewhat random output (in contrast to a compiler  which is a sentence recognizer). The idea is that we can take a grammar where each

A4  string of the form <string> is a non­terminal symbol that can be replaced using one of the  productions in the grammar. The file is filled with 'productions' such as: 
{  <conjunction>  and ;  but ;  yet ;  } 

Where: ·  each production is bracketed with {} ·  the first line in each production holds the name of the non­terminal left­hand­side  of the production (i.e., <conjunction>  in the example above) ·  each of the possible productions follows, terminated by a ';' (though shown on  separate lines this is not a requirement)  So the production above corresponds to <conjunction> ::= and | but | yet. Note  that the first production in the grammar file will always be the 'start' symbol for the  grammar defined by that file.  The program reads one of these grammar file (provided as a command­line argument)  and then generates text by starting with the start symbol and generating output by  replacing each non­terminal with a randomly chosen production for that non­terminal.  Obviously the production chosen may be a mixture of terminals and non­terminals so the  process continues until there are no more non­terminals to process. In addition, we can  weight the probability of a particular production being chosen by repeating it more than  once in the list of productions for a particular non­terminal. Productions can be  recursive, but must have at least one non­recursive form to prevent infinite loops.  A.3.2 Solution 
#imports the Stack namespace  source Stack.tcl  #return true if word is a non­terminal symbol  proc isNonTerminal word {  return [regexp \<*\> $word]  }  #return true if word is a nonterminal symbol  proc isTerminal word {  return [expr ![isNonTerminal $word]]  }  # [sets up our associative array]  proc getMap {filename} {  set map [list]  set options [list]  set _ON 1  set _OFF 0  set flag $_OFF  set text ""  set infile [open $filename r]

# [go through the file reading each line.]  while { [gets $infile line] >=0 } {  # [starts the grammar parsing]  if [expr ![string compare [string trim $line " "] "\{"]] {  set flag $_ON  set start $_ON  set text ""  set $options [list]  } else {  # [if its the first line after we begin this is a terminal]  if {$flag && $start} {  lappend map [string trim $line " "]  set start $_OFF  } elseif $flag {  set text ""  set options [list]  set text [string trim $line " "]  # [for each line after the starting line, add ]  # [the line into a list]  while {[gets $infile line] >=0 &&  $line != "\}"} {  set text [concat $text [string trim $line " "]]  }  # [associate the nonterminal symbol with the list we created]  set options [split $text ";"]  set size [llength $options]  lappend map [lrange $options 0 [expr $size ­ 2]]  set flag $_OFF  }  }  }  return $map  }  set generatedText ""  #Check that a file was given  #if not: print usage statement  if {$argc != 1} {  puts "Usage: tclsh db.tcl \$filename"  } else {  #check to see if the file given exist,  #if not: print "file does not exist"  if {[file exists [lindex $argv 0]]} {  #open a file (file name that is given)  set filename [lindex $argv 0]  # [set up the associative array]  set list [getMap $filename]  set startSymbol [lindex $list 0]  array set map $list  } else {  puts "No file exists by that name"  }  # [add the start symbol to the stack]  Stack::push $startSymbol  # [while the stack is not empty randomly generate text]

while {![Stack::empty]} {  # [if the next thing is a non­terminal]  if [isNonTerminal [Stack::peek]] {  # [get an item off the stack]  set current $map([Stack::pop])  set currentSize [llength $current]  # [randomly grab one of the expression associated to our ]  # [non­terminal]  set rndNum [expr int(rand() * $currentSize)]  set innerSize [llength [lindex $current $rndNum]]  # [add each item onto the stack]  for {set i [expr $innerSize­1]} {$i >= 0} {set i [expr $i ­ 1]} {  Stack::push [lindex [lindex $current $rndNum] $i]  }  } else {  # [set up the generated text]  set generatedText [concat $generatedText " "]  set generatedText [concat $generatedText [Stack::pop]]  }  }  # [print out generated text]  puts $generatedText  } 

A.3.3 Sample Grammar 
Super Hero Acticle  by Zachary A. Hayes (  {  <start>  <headline> <details> . ;  }  {  <headline>  HEROS ARE BUSY THIS WEEK SAVING <Object> ! ;  <Hero> DOES IT AGAIN ! ;  <Hero> SAVES THE DAY ! ;  <Hero> LONGTIME NO SEE ! ;  ALL HAIL <Hero> SAVER OF <Object> ! ;  }  ...  ... 

A.3.4 Sample Output 
The Incredible Hulk SAVES THE DAY ! Shanna Duckett uses beans to attack  benches . Captain America drives in but just then Shredder attacks  Sacramento, California . Teenage Mutant Ninja Turtles uses levitation  against Cobra Commander stopping him/her but just then Apokolips and  Doctor Doom uses spork, not quite a spoon or a fork, to attack The

Empire State Building . Zachary Hayes uses mental power against Kingpin  stopping him/her


Active State: Dynamic Tools for Dynamic Languages . 2006 . ActiveState Software Inc .  28 October 2006 .  Ousterhout, John . Tcl Developer X­change “History of Tcl” . October 2005 . 28 October  2006 . ActiveState .  Ousterhout, John. Tcl and the Tk Toolkit (Partial Draft). Addison­Wesley Publishing  Company Inc , 1993  Raines, Paul & Jeff Tranter . TCL/TK IN A NUTSHELL: A Desktop Quick Reference .  Sebastopol, CA: O’Reilly Media Inc , 1999  “Tcl Heritage” . 28 Oct 2006  Wikipedia: The Free Encyclopedia “Tcl” . 28 October 2006 . Wikimedia Foundation Inc .  28 October 2006 .  Sanfilippo, Salvatore . Tcl Wise: Guide to the Tcl Programming Language(Pre­Release/  Incomplete). November 6, 2006  Developer Connection “Tcl(n): Tcl Built­In Commands” November 6, 2006 .  l.ntcl.html

Master your semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master your semester with Scribd & The New York Times

Cancel anytime.