Version 22 of TCL programs for beginners 1-10

Updated 2005-11-25 14:45:45

Robert Abitbol The following basic programs written in TCL will give you a general introduction to the TCL syntax.

Code written by FW, LV, RS, BR, aa and GPS. Many thanks to them!


Re: TCL syntax

aa - Tcl syntax isn't anything like C syntax. It's unlike the syntax of most other popular languages. It's supremely simple and straightforward. These basic programs serve mostly to show the absence of the kind of incantations that are required when programming in a language like C.


The Endekalogue and this page

aa I think the Endekalogue provides a more useful introduction to Tcl syntax, though it's likely that only someone who is already familiar with Tcl's quoting and substitution rules -- and who isn't burdened by trying to see it in a C-like context -- will understand it easily.

Robert Abitbol The Endekalogue is fine but most people understand better through examples like we provide here. In any case the Endekalogue and this page provide two different approaches: the best of both worlds. Both can co-exist. Thanks for your understanding.


Program # 1: Hello world. How to start and end a program; how to write something on the screen

  puts "Hello world!"
  exit 0

---> Save the program with the extension:

BR Two of the implied questions seem non-Tcl to me. Q1: You don't "end a program." You write libraries and in the end you call one of the library functions to start the program. In this example the library function is already written, it's called "puts". This is a good mental model in other languages too, BTW. Anyway, "exit 0" is superfluous, just like exit(0) in a C main() function would be as well.

LV Actually, an exit 0 is not superfluous in a C main function. Since Tcl exec treats non-zero return codes as if they were errors, terminating a program - regardless of the langauge - with an explict return of 0 when the program is terminating succesfully - ensures that the tcl exec doesn't raise a false error condition. However, note that it appears that tcl uses an exit code of 0, by default, if no exit is provided, so there is no real need to end a tcl program with an explicit exit.

BR "[A]n exit 0 is not superfluous in a C main function". ?? This is becoming an argument about good C style ;-). In good style a C main() must have a "return 0" anyway, so what do I need "exit(0)" for?

BR Q2: Also you don't need to save the file with some pre-defined extension. The Tcl startup files are written in Tcl and they are called .tclshrc and .wishrc. Files with the extension .tml often contain Tcl code to produce HTML files etc. Tcl itself doesn't care what form the names of the files have.

LES: calling 'exit' at the end of every script can be a good habit. Especially if you use Windows and/or ActiveTcl and have .tcl files associated with wish. Scripts run with wish won't exit (and/or return output) until you close them manually if there is no exit command.

BR Ok, you got me there. In general, if you assume that your program might be called from wish, than it makes good sense to prevent the event loop in this way.


Robert Abitbol OK so I have the Tclkit and I want to execute a small function called Hello world. Can you tell how to go about it step by step?

LV Well, first I surely wouldn't call the function Hello World. While it is perfectly legal, why cause more grief than necessary?

Instead, what I would do is :

  1. create a text file called HelloWorld.tcl with the lines
        #! /path/to/tclkit
        puts "Hello World!"
        exit 0

Note that despite BR's comments above, I had no need to write a function and invoke it - I created a straight line program .

  1. Save the text file.
  2. From the command line, type:
        /path/to/tclkit HelloWorld.tcl

Note that if you are on Unix, there's no requirement to end the file name in .tcl . However, by doing so, then on Windows, one can associate the tclkit with the file. And Unix users who use a GUI file manager can do the same thing. And MacOS X users can do the same thing. Thus, instructions can be written in a more cross-platform manner.

Robert Abitbol I have the tclkit in c:\tcl kit\tclkit.exe. What do I put at the beginning of the program? c:\tcl kit\tclkit.exe ? And when I want to run the file I have coded, I'll copy it in the buffer than paste it in c:\tcl kit\tcl kit.exe?

LV On Windows, the first line is probably not relevant until you start using Cygwin or some other Unix emulation on MS-DOS package. It is my understanding that the default command processor on Windows ignores the #! line anyways. So on Windows, you would either type:

 tclkit.exe hellowworld.tcl

or you would go through whatever the steps are to associate tclkit as the program to use with files that end in .tcl .


Program # 2: an input is asked from the user; putting a variable in memory and printing it on the screen

  puts "Hey dude, how old might you be?"
  gets stdin Age
  puts "Dude, you are $Age years old but you look older."
  exit 0

Practice exercise:

Ask a person in which year he/she will retire.


Syntax of variables

So far as I know, variable names can contain pretty much anything, including spaces, and there's no requirement for the first letter to be capitalized. In fact, that would go against many programming "styles", where Capitalized and UPPERCASE and lowercase have specific implications. And it goes against the example given, which uses a variable named age with no upper case...or did until someone changed it to Age for no reason I can see.

BR Variables can have any string as their name. But to use the usual $name syntax, you want to restrict yourself to latin characters and digits.

For more information on Tcl variables, check out what kinds of variable names can be used in Tcl? and what kinds of variables can Tcl scripts use?


Program # 3: Very similar to # 2. But this time the variable will be a character or a series of characters (ex: a name)

FW: Not applicable, strings and ints are the same in Tcl. If you want to confirm the input was in integer form in the first example you can use [string is int].

LV Note that the requirements probably should read "this time the variable will hold a character...".

FW: Note that Tcl would do exit 0 automatically, unlike C, which would issue a warning without an explicit return. So in practice they would be left out, LV or put them in to make for a better comparison.

LV I put them in to make for a better comparison - but see my comments above about the cases where without the returns one could potentially end up with a problem.


What stdin stands for

FW: It stands for Standard Input. All programming languages support this, including C. It means the channel to receive input from (there's also an an stdout, and an stderr). This is usually commands typed in the console, but a program can be for example invoked by another program, which sends it data.


Program # 4: We ask a person his/her age. If it is under 20, we reply: "you are a child or a teenager". If it is 20 or over, we reply: "you are an adult now".

  puts "Hey dude, how old might you be?"
  gets stdin Age
  if {$Age < 20} { 
      puts "You are a child or a teen-ager"
  } else { 
      puts "You are an adult now" 
  }

[This is of course missing a load of error handling, right now all errors just cause a cryptic syntax error exception during execution.]

RS: Alternatively, one could write for the last 5 lines:

 puts "You are [expr {$Age<20? {a child or a teen-ager}: {an adult now}}]"

Robert Abitbol You would include all the ifs, else and put statements in one single statement. Very practical! : would mean "else"

You could say that : means "else", but you'd be glossing over the fact that it goes along with ? as part of the arithmetic if operator.'

aa - Watch out for hidden assumptions. Calling if and else "statements" betrays a fundamental lack of understanding of just how Tcl works. if is simply a command, just like any other command. Commands like Tcl's if and for might look familiar, but they're not built quite the way one usually thinks of them in a language like C. Read the documentation for if to see that it's a regular Tcl command with arguments.

In a smaller number of lines

 puts "Hey dude, how old might you be?"
 gets stdin Age
 puts "You are [expr {$Age<20? {a child or a teen-ager}: {an adult now}}]"

Program # 5: Very similar to program # 4 but a little more complex. We ask a person his/her age.

* If it is under 12, we reply: "you are a child".

* If it is between 13 and 19 we reply: "you are a teenager".

* Else we reply: "you are an adult now".'''

  puts "Hey dude, how old might you be?"
  gets stdin Age
  if {$Age < 12} {
    puts "You are a child"
  } elseif {$Age < 19} {
    puts "You are a teen"
  } else { 
    puts "You are an adult now" 
  }

In one statement

 puts "Hey dude, how old might you be?"
 gets stdin Age
 puts "You are a[expr {$Age < 12 ? " child" : ($Age < 19 ? " teen" : "n adult now")}]

Program # 6: Very similar to program # 5 but we introduce the concept: between ... and ...

---> We ask a person his/her age.

* If it is between 0 and 12, we reply: "you are a child".

* If it is between 13 and 19 we reply: "you are a teenager".

* If is over 19 (else), we reply: "you are an adult now".

  puts "Hey dude, how old might you be?"
  gets stdin Age
  if {$Age >= 0 && $Age <= 12} {
    puts "You are a child."
  } elseif {$Age >= 13 && $Age <= 19} {
    puts "You are a teen."
  } elseif {$Age > 19}  { 
    puts "You are an adult now."
  }

Huh? This code snippet makes no sense to me, and has errors galore when I cut and paste it into an interpreter. Is "between ..." some new 8.5 or 9.0 syntax for the if command? If so, this example doesn't do a very good job of illustrating it, because I don't see the word "between" anywhere. Also, I don't see how ...{ can do quoting, which seems to be implied by the rest of the example. This whole example has me shaking my head wondering what's going on.

LV I've modified the above so that it should work now. However, I'd really code it like this:

  puts "Hey dude, how old might you be?"
  gets stdin Age
  if {$Age <= 12} {
    puts "You are a child."
  } elseif { $Age <=19 } {
    puts "You are a teen."
  } else {
    puts "You are an adult now."
  }

This seems to be a use case for the comb pattern:

 puts "You are a(n) [comb $Age {child 13 teen 19 adult}]"

just to show (off) that functional programming can be put to surprising uses all over the place. In Tcl, you can code like in C, but maybe you shouldn't...


Comments

Er... thanks for the credit, which I have removed myself. But I don't remember writing any of the code above. Maybe some other time. - LES


FW: Personally, I think this is a pretty scatterbrained method for teaching, barely useful to anyone - except possibly to you, since you get to pick the examples ;). Just a list of broken English descriptions and nonstandard code (capitalized vars etc.).

Robert Abitbol: It is a very traditional, very orthodox, conventional, time-honoured way to teach a programming language. Maybe instead of criticizing, you can try to do better, Alex. :) I don't mind your taking the initiative. What I mind is people who criticize and have nothing to offer in return.

JQB: What we have here are two descriptions of this page, the first accurate and the second not. I think Mr. Abitbol should learn some humility. What people who criticize have to offer is criticism, something that mature, intellectually honest people understand and accept. My critical comment is that a page describing programs for beginners should not be written by a beginner -- in programming, Tcl, teaching, and critical thinking, apparently. The result will invariably be useless junk or worse, which is what this page is -- any beginner will be harmed by reading it. Update: Good lord, it's much worse than I imagined! This isn't just the behavior of a beginner, it's a pattern of behavior from an old hand with a long record of WikiDisruption; see http://downlode.org/log/2004-06-16/Robert_Abitbol

aa - The "orthodox" way of teaching a programming language is to explain its syntax and any required structures (such as main() in C). Indeed, the stated purpose of this page is to be "a general introduction to the TCL [sic] syntax." But none of the examples here have anything to do with explaining Tcl's syntax. I'm not even sure you know what Tcl's syntax is, Robert -- it certainly isn't evident from the choice of programming problems.

Robert Abitbol again: I believe that my method is certainly not the best but at least I am offering something! You don't. Sort of like the man who always criticizes the baker and says that his bread is terrible. His bread might not be the best in the world but at least noone starves in the village. And what does the critic offer to replace the bread? Nothing. And the whole village starves. Quite a good critic! Please think twice before you write, Alex! This is not your smartest comment!

aa again: The Tcl'ers Wiki is chock full of short, clear, well-presented examples of Tcl code. Once the language's syntax is explained -- essentially the parsing rules codified in the Endekalogue/Dodekalogue -- the programs here are more than adequate as learning resources. They aren't a tutorial, but if a tutorial is what you want, you could have looked for one before starting one based on a too-limited knowledge of the subject. Jumping in and filling what you perceive as a gap is admirable, but it might have been a better use of your time to ask first whether what you're looking for already exists. In this case, it most certainly does: Tcl Tutor is one of the best, and Online Tcl and Tk Tutorials lists a bunch more.


See also Endekalogue, Tcl cheat sheet and 99 bottles of beer.


slebetman Robert asked, I'll deliver. This is my understanding of tcl syntax: The following basic programs written in TCL will give you a general introduction to the TCL syntax.

The Zen of the Tcl written by slebetman

Tcl is probably not like any other programming language you are likely to encounter. The best way to approach Tcl is to think of the command line, be it DOS or bash or tcsh or Cisco's telnet shell.

All statements in tcl work just like running a program form the command line. That is, the first word is a command and the following words are parameters to that command. For example, in DOS to list the contents of a directory you would type:

  dir c:\path\to\folder

in tcl you would write:

  glob /path/to/folder/*

Just like in DOS, the first word of a tcl statement is always a command. Simple isn't it?

Any Comments?..

In tcl any command (first word in a statement) that begins with the # character is ignored. This is how one inserts comments. Comments are nice since it alows you do document things which may not be obvious in your code. At university, my Software Engineering professor gave 40% of marks in coding to comments. So comment away...

   #This is a comment
   # the tcl interpreter will ignore comments so you can say whatever you like ;-)

Variables and Values(I'm out of clever titles here)

In all programming languages, you use variables to store values. Some languages prevent you form storing different kinds of values into different kinds of variables. But we'll have none of that here. In Tcl a variable can hold anything (even complete programs if you want to). Variables will even hold your hand:

  set my_variable "your hand"

well.. maybe not your hand but the code above stores the string "your hand" into a variable called my_variable. The set command is used to assign values to variables. It can also be used to get the value contained by the variable:

  #assign value:
  set new_var 100

  #get value and print it on screen
  puts [set new_var]

Programmers usually don't like typing too much. So Tcl provides a kind of shortcut to get the value of variables without using the set command. Simply add a $ sign in front of the variable to get its value:

  #another way to get value of variables
  puts $new_var

  #you can even assign values of other variables to a varaible:
  set my_variable $new_var

Notice that when one sets a variable, one uses the variable without the $ sign. This is because the $ sign is not used to signify a variable like in Perl but is merely a shortcut for getting its value.

Just for fun, what do you think happens in the following code?

  set foo "this is cool"
  set bar foo
  puts [set $bar]

My Group, Your Group, Everyone Needs Groupings

There are several things I did not explain in the examples above. One of which is the use of the double quotes ("). I know what you're thinking: I know that, it's a string. Correct.. but not quite. You see, in Tcl, everything is a string until it needs to be something else. Even 200 is a string until you try to add 1 to it. What the quotes represent in tcl is grouping - a far simpler and powerful concept.

Lets take a look at the 'set' command. It accepts either one or two parameters. If there are two parameters than the second parameter is a value to be assigned to the first parameter. What if our string consists of more than one word? Trying to do:

  set foo this is cool

will result in error: wrong # args: should be "set varName ?newValue?" So tcl provides mechanisms to group words together. In the earlier example, foo is the first parameter and "this is cool" is the second, grouped by the quotes.

Tcl provides two ways to group things: the double quotes " and curly braces {}. The above example would also work with:

  set foo {this is cool}

What's the difference? Why two kinds of groupings? Well, things grouped with the double quotes will go through substitution. Things grouped with braces will be left alone. You're saying what??.. Lets see an example:

  set foo 100
  puts {example1 $foo}
  puts "example2 $foo"

The above code will print out:

  example1 $foo
  example2 100

that's because the first puts statement is left alone while the second one is substituted.

Substitues..

We have seen one kind of substitution already. That is the $ shortcut. This is called variable substitution because it replaces the variable with its value. Substitutions are what makes Tcl tick. It is a powerful, flexible and simple concept. There are three kinds of substitutions in Tcl: variable substitutions, command substitutions and backslash substitutions.

We have already seen variable substitution and it is explained above. It simply substitutes the value of the variable in place of the variable itself when a $ sign is added in front of the variable.

Command substitution is similar in that it substitutes the result of a command in place of the command. We have in fact already seen this above but I did not explain it. Basically statements between square brackets are treated as commands and are evaluated. The result is then substituted in its place. For example:

  set bat "a list of files in the current directory: [glob *]"

The glob command is evaluated and its result is inserted into the string which is then assigned to the variable bat. We have seen similar syntax in the various set and puts examples above.

...............

oh my, that was long... I'm tired now and leave it to the rest to continue this. Anyway, I think only backslash substitution is left. And the order of evaluation. The rest are just commands and not really 'syntax'. This is supposed to be an intro to tcl 'syntax' isn't it?


JM good job! I think this section (by slebetman) is a clear explanation for the beginners (as myself) and it deserves its own page.


Category Tutorial