originally by [slebetman], for those who are [Learning Tcl] ** The Zen of the Tcl ** 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 from 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: ======none 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? The ''glob'' command is just one of the commands available in Tcl. Another useful command is the ''puts'' command. It simply prints things out on the screen. Try it: ====== puts "Hello World!" ====== You may think of it as '''put''' '''s'''tring but I usually think of it as the plural of put (since it can output more than one character). Notice that ''puts'' is similar to the ''echo'' command in DOS and Unix shells. Again, this shows how simple Tcl is. ** 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 they allow you do document things which may not be obvious in your code. ====== #This is a comment # the Tcl interpreter will ignore comments so you can say whatever you like ;-) ====== ** Variables and Values ** In all programming languages, you use variables to store values. Some languages prevent you from 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 uses the ''set'' command on 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] ====== In the first statement, the variable ''foo'' is set to hold the string ''"this is cool"''. The variable ''bar'' is then set to the word ''"foo"''. Notice that there is no '''$''' sign in front of ''foo''. This means that ''bar'' is not assigned the '''value''' of ''foo'' but just simply the word ''foo''. The interesting part is the third statement. The ''set'' command is used to get the value of ''$bar''. Since ''bar'' itself contains the word ''foo'', what happens is we get the value contained in the value of ''bar''. Confused? Let's examine the third line step by step. The '''$''' sign is a shortcut to get the value of a variable. So ''$bar'' returns the word ''foo''. The ''set'' command then gets the value of ''foo'' and returns the string ''"this is cool"''. The third line can also be written as: ====== puts [set [set bar]] ====== but writing ''$$bar'' does not work. This is because '''$$''' is not something Tcl understands. ** 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. Let's take a look at the ''set'' command. It accepts either one or two parameters. If there are two parameters then the second parameter is a value to be assigned to the first parameter (which is a variable name). What if our string consists of more than one word? Trying to do: ====== #warning, bad code ahead! set foo this is cool ====== will result in ======none error: wrong # args: should be "set varName ?newValue?" ====== why? because we are given '''set''' four parameters, instead of two. we should write: ====== set foo "this is cool" ====== 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. ** Substitution ** 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 a statement between square brackets '''[[ ]]''' is treated as a command and is 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. Backslash substitution is very similar to C/C++. The following are backslash substitutions understood by Tcl: * \a Audible alert (bell) (0x7). * \b Backspace (0x8). * \f Form feed (0xc). * \n Newline, LF (0xa). * \r Carriage-return, CR (0xd). * \t Tab (0x9). * \v Vertical tab (0xb). Also, if a '''\''' is followed by up to 3 digits of numbers, than it is treated as an octal value for a character and the actual character is then substituted in its place. Any other character following a '''\''' is replace with itself. This is an 'escape' mechanism that enables you to include special characters: ====== puts "This is how you print the double quote (\")" ====== In addition, if a backslash '''\''' appears at the end of a line, then that line continues on to the next line: ====== puts \ "Continued from the line above" ====== This is to allow a long line of code to be split into multiple lines if you run out of space in your text editor. See also: http://www.tcl.tk/man/tcl8.4/TclCmd/Tcl.htm ---- ** What is a list? ** In Tcl, everything is a string. But what is a list? It is basically, a string in which elements are separated by spaces. ====== set a "A B C" lindex $a 0 ====== The above commands return : ======none A B C A ====== [lindex] returns a list element, located at a given index. Indices start at 0. ====== set a {A B C} lindex $a 1 ====== returns "B". -- [Sarnold] 2005/11/27 [DKF]: But it's not just that, since you can put lists inside lists, like this: ====== set a "A {B C} D" lindex $a 1 ====== returning: ======none A {B C} D B C ====== Because of this sort of thing, you need to remember that not all strings are lists. Instead, use the [split] command to convert a string into a list of words. ---- [JM]: slebetman, I would like to participate in this page, I can suggest an idea that I think fits, then if you agree I can insert the text where I think it belongs, so I don't mess original idea of this page. example: for the "any comments?" section, we can include that, a common, alternative way to insert comments in tcl (and I think not just in tcl) is by means of: ====== if {0} { these are the comments } ====== which is really code that is never executed. [slebetman]: I'd wait until we introduce the 'if' command. I know '''if''' is obvious to anyone who is used to programming in any language. But I want to impress the ''essence of Tcl'' to newbies. Mixing syntax and command is not good in my view. But thanks for your support. Please edit away any mistakes that you find here. But please refrain from commenting ''in-line''. Comment at the bottom. In-line comments in the text itself is to be considered transient and may be edited away once corrections are made. Also, if you find ways to re-phrase sentences and paragraphs in a more 'friendly' manner, please do so (in-line comments may be appropriate in this case if there is no consensus yet). I want to keep the tone of this introduction fun, friendly and informal, sort of like for-dummies, maybe even more fun. Humor is very much encouraged but not at the expense clarity: fun, not flippant. Anyway, I think the syntax rules are covered. Feel free to start describing commands like '''if''', '''proc''' etc. Don't worry about which comes before/after which. We can always edit and re-arrange chapters later. [Lars H] 2005-11-28: Well, there's no mention of \x and \u substitution. I find \u interesting to mention, since it points to the fact that Tcl is not restricted to 8-bit characters, which however many other languages are. [slebetman]: Good catch. Missed that. I'll be adding it later when I have time. Or you are free to do it yourself. [escargo] 2004-11-28: I don't like spoiling the fun, but I think it's worthwhile mentioning some of the "gotchas" of Tcl. For example, that comments require balanced delimiters, that commands that take ''similar'' parameters don't necessarily take ''identical'' parameters (that is, some things can be more irregular than other languages because there isn't an overarching grammar that enforces regularity). [AET] 2005-11-29: I agree, but there are many places where such information interrupts the learning flow. A simple '''DO''' and '''DONT''' list is less confusing for a [beginner]. And please, PLEASE resist the temptation (that so many have fallen to) to describe a new subject in terms of ''Here's some code that doesn't work, and here's why . . ''. A beginner needs to see and absorb simple, clear and above all CORRECT code. Please also keep debate of finer points of style, completeness, unusual exceptions etc. to other pages. [slebetman]: I agree with [AET]. I intend to give new users the 'feel' of Tcl which I and a lot of others found lacking in [TCL programs for beginners 1-10]. This is meant as an introduction, not a complete description. By the way, I always wondered why the matching bracket thing is not documented in the 11 rules of Tcl: http://www.tcl.tk/man/tcl8.4/TclCmd/Tcl.htm Also, with regards to wiki rules about editing other's post. If the changes in the comments are implemented, can I delete the comment? Also, I hope others won't mind if I later re-arrange parts of this page to make it more coherent overall. [Lars H]: The "no unmatched braces in comments" restriction is only relevant in bodies (of [proc], [foreach], [while], etc.), so it is natural to bring up in that context, but this is too early -- there hasn't yet been any example where a comment with an unmatched brace would spoil anything! ---- ** DO ** * Do write lots of comments in your code about what your code does, what you tried that didn't work (and why, if known). * Do study the documentation and others' code to understand 'upvar', 'uplevel'. ---- ** DON'T ** * Don't have unmatched brackets ANYWHERE, including comments. Use a text editor that helps you by showing bracket matching. * Don't expect to use an array in a proc till you understand 'upvar'. ([CL] strongly disagrees.) * Don't expect to drive external programs easily till you get the hang of 'exec'. ---- ** Especially Useful Tcl Features ** * [foreach] is wonderful. Simple and powerful. ---- ** Code reusing and packaging ** * [tcllib] is full of useful code. Try to use it as much as possible, a wide use of [tcllib] really saves time, and it is frequently updated. * If you need speed, be aware that Tcl can be extended easily (using [C],[C++]...). Avoid writing your own extensions if existing ones can do the job. * Do split your code into different [namespace]s (and files) when it overcomes ca. a thousand lines. ---- ** Regarding Variables and Values example ** ====== set foo "this is cool" set bar foo puts [set $bar] puts [set [set bar]] ====== yet another line to add to example code: ====== puts [expr $$bar] ====== [wjk] -- Totally agree with comment below by [Lars H] [Lars H]: I don't think that would be a good idea, because [[expr $$bar]] combines two bad habits for a Tcl programmer: not bracing [expr]essions and $ signs that fail to substitute. It can at best be a specimen for illuminating some of the odd quirks of the language, but it is definitely not something beginners should be exposed to. ---- ** See Also ** [Learning tcl]: the first stop for those learning Tcl [Tcl Advocacy]: Why Tcl is a great language to learn * "Five Surprises from Tcl" [http://www.devsource.com/article2/0,1759,1778148,00.asp] is probably best for programmers who don't work with the language but think they already knows its capabilities and limits * "Tcl The Misunderstood" [http://antirez.com/articoli/tclmisunderstood.html], a marvelously-written piece by [antirez] * All [Tcl]-related tutorials [http://wiki.tcl.tk/2?tutorial] <> Tutorial