Tcl
From Wikipedia, the free encyclopedia
This article includes a list of references or external links, but its sources remain unclear because it lacks in-text citations. You can improve this article by introducing more precise citations. |
This article or section may contain an excessive amount of external links. Please improve this article by incorporating them into the appropriate end section, or by converting them to inline citations |
Tcl | |
---|---|
Paradigm | multi-paradigm: object-oriented, functional, procedural, event-driven programming |
Appeared in | 1988 |
Designed by | John Ousterhout |
Developer | John Ousterhout |
Latest release | 8.5.2/ March 28, 2008 |
Typing discipline | dynamic typing, everything can be treated as a string |
Major implementations | ActiveTcl |
Influenced | PowerShell[1] |
Website | http://www.tcl.tk |
Tcl (originally from "Tool Command Language", but nonetheless conventionally rendered as "Tcl" rather than "TCL"; pronounced as "tickle" or "tee-cee-ell"[2]) is a scripting language created by John Ousterhout. Originally "born out of frustration"[3]—according to the author—with programmers devising their own (poor quality) languages intended to be embedded into applications, Tcl quickly gained wide acceptance on its own and is generally thought to be easy to learn[4], but powerful in competent hands. It is most commonly used for rapid prototyping, scripted applications, GUIs and testing. Tcl is used extensively on embedded systems platforms, both in its full form and in several other small-footprinted versions. Tcl is also used for CGI scripting and as the scripting language for eggdrop bots.
The combination of Tcl and the Tk GUI toolkit is referred to as Tcl/Tk.
Contents |
[edit] Features
Tcl's features include:
- Everything is a command, including language structures. They are in Prefix notation.
- Commands can be variadic.
- Everything can be dynamically redefined and overridden.
- All data types can be manipulated as strings, including code.
- Extremely simple syntactic rules.
- Event-driven interface to sockets and files. Time-based and user-defined events are also possible.
- Flexible scope, with variable visibility restricted to lexical (static) scope by default, but uplevel and upvar allowing procs to interact with the enclosing functions' scopes.
- Simple exception handling using exception code returned by all command executions.
- All commands defined by Tcl itself generate informative error messages on incorrect usage.
- Readily extensible, via C, C++, Java, and Tcl.
- Interpreted language using bytecode for improved speed whilst maintaining dynamic modifiability
- Full Unicode (3.1) support, first released 1999.
- Platform independent: Win32, UNIX, Linux, Mac, etc.
- Close integration with windowing (GUI) interface Tk.
- Easy to maintain code. Tcl scripts are often more compact and readable than functionally equivalent code in other languages.
- Can be used for many purposes, and in many environments: as a text-only scripted language, as a GUI-capable language for applications, as an embedded language in: web pages (server-side; or client-side, as Tclets), and databases (server-side, in PostgreSQL).
- Exists as development version (e. g. ActiveState Tcl), as tclkit (kind of runtime version, only about 1 megabyte in size), as starpack (single-file executable of a script/program), as BSD licensed freely distributable source
Tcl did not originally support object oriented syntax, being a functional language, but recent versions do support extensions which provide OO functionality, such as the XOTcl extension to Tcl. Other OO extensions also exist, such as incr Tcl, Snit, and STOOOP (simple tcl-only object-oriented programming).
Functional programming can easily be done in Tcl, as higher-order functions or functional abstractions are built into the language, though it is not widely used for this purpose. As an example, consider the ease with which two functions can be composed:
proc o {f g x} {$f [$g $x]}
[edit] Syntax
[edit] Very simple and consistent syntax
Tcl has a very simple syntax which is applied in a consistent way. A Tcl script consists of several commands. A command is a list of words separated by whitespace.
word0 word1 word2 ... wordN
The first word is the name of a command, which is not built into the language, but which is in the library. The following words are arguments. So we have:
commandName argument1 argument2 ... argumentN
Practical example, using the puts command which outputs a string, adding a trailing newline, by default to the stdout channel:
puts "Hello, world!"
Any argument may be replaced by another command in square brackets. The subcommand is evaluated first and the result is substituted as the argument. Alternatively, any argument placed in curly braces will not be evaluated, but rather will be handed directly back to the original command as an argument.
To summarize: there is one basic construct (the command) and a set of simple substitution rules, and only the square brackets, the curly braces, quotes, and the backslash have special meaning. The single equality sign (=) for example is not used at all, and the double equality sign (==) is the test for equality, and even then only in expression contexts such as the expr
command or the first argument to if
.
All commands have the same structure: a keyword which is followed by several parameters. A command is terminated by a newline or a semicolon. Even comments are just commands which happen to do nothing.
Tcl is not statically typed: each variable may contain integers, floats, strings, lists or any other value.
[edit] Symbols with a special meaning
$ |
variable substitution (e.g. $argv0 might be replaced by /usr/bin/somescript.tcl) |
[] |
subcommand substitution (e.g. [pwd] might be replaced by /home/joe) |
"" |
word grouping with substitutions (e.g. "you are $user" is one word; substitution still occurs) |
{} |
word grouping without substitutions (e.g. {you are $user} is one word, where $user is not replaced) |
\ |
backslash substitution/escape (see Tcl documentation for full list) or statement continuation (by default, statement ends with the line) |
# |
comment (only at the beginning of a statement) |
; |
statement separator |
:: |
namespace path separator for variables or commands (e.g. ::foo::bar) |
{*} |
expand rest of word as list (only at beginning of a word; introduced in Tcl 8.5) |
[edit] Some examples of commands
Assignments are made with the command set, i.e., the equal sign ('=') is not used for assignments.
set someVariable value
'While' loops are implemented by the command while which takes two arguments. The first argument is a Tcl expression (expressions are written in what is essentially a miniature language for doing C-style math and comparison expressions). The second argument is the script to run on every iteration. They are generally put in curly braces to avoid immediate execution.
while { [aTclCommandWhichEvaluatesToABoolean] } { aTclCommand anotherTclCommand .... }
If command
if {$x < 0} { set x 0 }
Switch command
switch -glob -- $var { {see} - {saw} - {seen} { puts “All mean the same thing!”} }
Commands may have no arguments
pwd
gives back the current working directory. With
set wdir [pwd]
you store the string describing the working directory in the variable wdir.
A command may give back as a result a list
glob aPattern
gives back a list of file names in the working directory whose names match aPattern.
[edit] Procedures
Procedures are defined as follows
proc nameOfProc { argumentList } { # .... # .... }
[edit] Associative arrays
The following code snippet creates and initializes an associative array which in other languages is called a map, dictionary, or hash table.
set capital(India) Delhi set capital(France) Paris set capital(Italy) Rome set capital(Germany) Berlin set capital(Poland) Warsaw set capital(Russia) Moscow set capital(Spain) Madrid
To query it and put the result on standard output use
puts $capital(Italy)
To get a list of all countries for which a capital is defined use
array names capital
The result is unsorted because Tcl arrays are based on hash tables.
Poland Spain Russia Germany Italy France
If you like to have it sorted use
lsort [array names capital]
Note however that arrays are collections of variables, not first-class objects, and cannot be freely passed around the way strings are. The commands
set CapitalCopy $capital
And
DoSomethingWith $capital
both produce the error message
can't read "capital": variable is array
In general, note that Tcl has a different concept of references than some people might expect. To refer to an array (to pass it by reference), give its variable name:
proc demo { arrName } { upvar 1 $arrName arr ;# tie the reference to a local name # do something with arr }
To pass the contents of an array by value, use array get or array set. For example, to copy one array to another:
array set Newarr [array get Oldarr]
For pure-value associative arrays, Tcl introduced the dict type in version 8.5.
[edit] Variable scope
For a more detailed explanation of variable scope in tcl, visit here.
When referring to variables inside a procedure, the program will (by default) only recognize variables that were also defined in that procedure. Another way of saying this is that the program will only recognize local variables by default.
Here is an example program:
#! /usr/bin/env tclsh set gvar "123" ; # this is a variable created in the global namespace proc nest1 {} { set lvar "This is a test" ; # a local definition of lvar (a variable # within the local namespace) puts "$lvar"; # this variable is local to nest puts "$gvar" } nest1 puts "$lvar"
On line 6, the command 'puts "$gvar"' will create an error because it is technically only referring to the variable with that name that is also within the local namespace. However, there is no variable "gvar" within that local namespace because gvar was not declared in the nest1 namespace.
Also, on line 9, the command 'puts "$lvar"' will create an error because it is looking for a variable called lvar within the current namespace (which happens to be the global namespace). Since there is no lvar that was globally declared, an error will occur.
This will fix the first problem:
# ... proc nest1 {} { global gvar set lvar "This is a test" puts "$lvar"; # this variable is local to nest puts "$gvar" } nest1 puts "$lvar"
The global call specifically told the program to look for the subsequent variables in the global namespace. But this still doesn't fix the second problem. If you want to be able to recall the variable lvar from global scope, you need to declare it as being within the global scope. Here is how you could accomplish that:
# ... proc nest1 {} { set ::lvar "This is a test" puts "$::lvar"; # this variable is local to nest puts "$::gvar" } # ...
By adding the namespace path separator '::' without specifying a sub-namespace (for example '::IAmASubNamespace'), you have made it clear to the program that you are actually declaring and defining a variable inside the global namespace.
If you are doing something where speed really matters, you can find that relevant information here.
[edit] Interfacing with Other Languages
Tcl interfaces natively with the C language.
[edit] C++ Interoperability
Please help improve this article or section by expanding it. Further information might be found on the talk page or at requests for expansion. (January 2008) |
[edit] Java Interoperability
Please help improve this article or section by expanding it. Further information might be found on the talk page or at requests for expansion. (January 2008) |
[edit] Extension packages
The Tcl language has always supported extension packages, which provide additional functionality (such as a GUI, terminal-based application automation, database access, etc.)
[edit] Tk
The most popular Tcl extension is the Tk toolkit, which provides a graphical user interface library for a variety of operating systems. Each GUI consists of one or more frames. Each frame has a layout manager.
[edit] Tile/Ttk
Tile/Ttk is a styles and theming widget collection which can replace most of the widgets in Tk with variants which are truly platform native through calls to an operating system's API. Themes covered in this way are Windows XP, Windows Classic, Qt (which hooks into the X11 KDE environment libraries) and Aqua (Mac OS X). A theme can also be constructed without these calls using widget definitions supplemented with image pixmaps. Themes created this way include Classic Tk, Step, Alt/Revitalized, Plastik and Keramik.
Under Tcl 8.4, this package is known as Tile, while in Tcl 8.5 it will be included in the core distribution as Ttk.
[edit] Itcl/IncrTcl
Itcl is an object system for Tcl. Please see the full article at Itcl for details.
[edit] Tcllib
Tcllib is a set of scripted packages for Tcl that can be used with no compilation steps. Please see the full article at Tcllib
[edit] Databases
A number of database extensions are available:
|
|
|
and many, many others - see the Tcl/Tk Wiki, specifically the Tcl/Tk Wiki Database Category.
[edit] Expect
The Expect package provides tools for automating interactive non-GUI programs, and is built on top of Tcl.
[edit] Examples
The following are simple code snippets that can be pasted directly into any Tcl shell.
[edit] Adding Numbers
Method (A) - Adding using a 'foreach' loop
set numbers {1 2 3 4 5 6 7 8 9 10} set result 0 foreach number $numbers { set result [expr {$result + $number}] } puts $result
Method (B) - A much more elegant way of adding numbers using the 'join' command
set numbers {1 2 3 4 5 6 7 8 9 10} puts [expr [join $numbers +]]
Method (C) - Use the addition command in conjunction with list expansion syntax
namespace import tcl::mathop::+ set numbers {1 2 3 4 5 6 7 8 9 10} puts [+ {*}$numbers]
[edit] Echo server
A simple working example, demonstrating event-based handling of a socket, follows.
#!/usr/bin/env tclsh # echo server that can handle multiple # simultaneous connections. proc newConnection { sock addr port } { # client connections will be handled in # line-buffered, non-blocking mode fconfigure $sock -blocking no -buffering line # call handleData when socket is readable fileevent $sock readable [ list handleData $sock ] } proc handleData { sock } { puts -nonewline $sock [ gets $sock ] if { [ eof $sock ] } { close $sock } } # handle all connections to port given # as argument when server was invoked # by calling newConnection set port [ lindex $argv 0 ] socket -server newConnection $port # enter the event loop by waiting # on a dummy variable that is otherwise # unused. vwait forever
[edit] Digital clock
Another example using Tk (from A simple A/D clock) and timer events, a digital clock in four lines of code:
package require Tk proc every {ms body} { eval $body after $ms [list every $ms $body] } pack [label .clock -textvar time] every 1000 {set ::time [clock format [clock seconds] -format %H:%M:%S]} ;# RS
Explanation: the first line loads the Tk package, the second (which actually continues over 4 lines) defines a command, "every", which re-schedules an action ('body') every 'ms' milliseconds; the third creates a label whose content is bound to the variable 'time' and arranges for it to be displayed on the screen; the fourth line arranges so that the variable 'time' is updated to formatted local time every second.
Note that the "every" command treats its first parameter as a number and its second parameter as a script, resulting in correct calls being those programs that pass in arguments that look like those pieces of syntax. However, the Tcl interpreter assigns no special syntactic interpretation to either argument, meaning that the code is free to interpret those arguments as desired. (By contrast, a language using a conventional BNF description could only achieve the equivalent functionality by defining "every" as a keyword, adding extra syntax to mark the executable argument, or by making the curly braces deeply magical indeed, possibly requiring a more complex declaration.)
[edit] List of content of associative array
The array tcl_platform contains a set of properties describing the platform that the Tcl interpreter is executing on. A list of the names of the properties is obtained by
array names tcl_platform
The following snippet lists them together with their values.
foreach i [array names tcl_platform] { puts [ concat $i= $tcl_platform($i) ] }
If the properties should be sorted by name, it is best to do that first, like this.
foreach i [lsort [array names tcl_platform] ] { puts [ concat $i= $tcl_platform($i) ] }
This also demonstrates how commands may be nested. In fact they may be nested to any depth. If you want it fancier (keys padded with blanks so that the equal signs align) just use the parray procedure, that comes delivered with Tcl.
Finally, if the contents of the array is just for machine consumption, there is a separate subcommand of array to do that:
array get tcl_platform
[edit] Intersection of two sets
The filter procedure returns those elements of the list where the script returns TRUE:
proc filter {list script} { set res {} foreach e $list {if {[uplevel 1 $script $e]} {lappend res $e}} return $res }
The in procedure is shorthand for list inclusion:
proc in {list e} { expr {[lsearch -exact $list $e]>=0} }
Testing:
% filter {a b c} {in {b c d}} b c
[edit] Factorial
proc ! x {expr {$x<2? 1: $x*[! [incr x -1]]}}
This demonstrates that any string (in this case, "!") can be a command name, and the ?: operator as from C is available in Tcl expressions too. Also, recursion (let the function call itself again) is easily possible, although Tcl has no tail call optimization so the maximum depth of recursion is restricted.
For comparison, here is the iterative variant which, together with the big integers available from Tcl 8.5, allows very large factorials:
% proc ! x { set res 1 while {$x>1} {set res [expr {$res*$x}]; incr x -1} set res } % ! 32 263130836933693530167218012160000000
[edit] History
The Tcl programming language was created in the spring of 1988 by John Ousterhout while working at the University of California, Berkeley.
Date | Event |
---|---|
January 1990 | Tcl announced beyond Berkeley (Winter USENIX). |
June 1990 | Expect announced (Summer USENIX). |
January 1991 | First announcement of Tk (Winter USENIX). |
June 1993 | First Tcl/Tk conference (Berkeley). [table] geometry manager (forerunner of [grid]), [incr Tcl], TclDP and Groupkit, announced there. |
September 2002 | Ninth Tcl/Tk conference (Vancouver). Announcement of starkit packaging system. |
(Need rest of potted history!)
Tcl conferences and workshops are held in both the United States and Europe.
- Tcl2007 is scheduled for New Orleans in September 2007; see: http://www.tcl.tk/community/tcl2007/ for more information. Expected to include the formal announcement of Tcl/Tk 8.5b1.
[edit] References
- John K. Ousterhout, Tcl and the Tk Toolkit, Addison-Wesley, Reading, MA, USA, ISBN 0-201-63337-X, 1994.
- Brent B. Welch, Practical Programming in Tcl and Tk, Prentice Hall, Upper Saddle River, NJ, USA, ISBN 0-13-038560-3, 2003.
- J Adrian Zimmer, Tcl/Tk for Programmers, IEEE Computer Society, distributed by John Wiley and Sons, ISBN 0-8186-8515-8, 1998. (Several chapters available online.)
- Mark Harrison and Michael McLennan, Effective Tcl/Tk Programming, Addison-Wesley, Reading, MA, USA, ISBN 0-201-63474-0, 1998
- Mark Harrison (ed), Tcl/Tk Tools, O'Reilly Media, ISBN 1-56592-218-2, 1997
[edit] Notes
- ^ Windows PowerShell : PowerShell and WPF: WTF
- ^ From the Tcler's Wiki Tcl vs. TCL
- ^ From the inside flap of Tcl and the Tk Toolkit, ISBN 0-201-63337-X
- ^ Flynt, Clif [2003]. "Tcl/Tk - A developer's guide", First edition (in english), Morgan Kaufmann Publishers, 759. ISBN 1-55860-802-8.
[edit] See also
[edit] External links
[edit] Main Tcl developer sites
- Tcl Developer Xchange Main Tcl developer site
- Getting started with Tcl
- Tcl Tutorial
- Tcl Documentation, and Tcl Manual Pages
- History of Tcl by the creator of the language.
- Tcl'ers Wiki
[edit] Tcl distributions
- ActiveState's Tcl distribution for MS Windows, Mac OS X, Linux, Solaris, AIX, and HP-UX, with numerous libraries.
- WinTclTk open-source MinGW-based distribution for Microsoft Windows with extensions
[edit] Tcl tutorials, books, etc.
- Tcl FAQ
- A Tcl (Tutorial for Cool Languages) for Tcl/Tk
- Older Tcl Contributed Sources Archive
- Open Directory: Tcl/Tk
- Tcl programming source code wiki at CodeCodex
- TclLink Tcl/Tk Directory
- CiteSeer Citations
- A Short TCL Tutorial
- Tclwise, a book on Tcl programming with online chapters by Salvatore Sanfilippo.
- The Jim Interpreter, is a small footprint implementation of the Tcl programming language.
- An article on Software testing with Tcl for Apache Rivet
- Tcl for Web Nerds - A Tcl tutorial with emphasis on its use in web development.
- MyrmecoX Studio - An IDE for Tcl and Dynamic Languages Applications.
- Equi4 Software - Tclkits, Starkits, Starpacks, Metakit and more
- TclBridge - ActiveX/COM integration for Tcl/Tk.
- http://www.tclscripting.com News and articles on software development with Tcl/Tk
- Tcl the misunderstood An essay describing the language's features
- The Simple Development Library A collection of commands and utilities aimed towards assisting software development in Tcl.
- Puppy Linux (extensively uses Tcl/TK for systems administration and configuration)