```Tcl Programming:
Theory & Practice
Presented By:
Sunil Ramesh
Origins of Tcl
⋋-Calculus - 1930
LISP - 1950
TCL - 1990
Alonzo Church,
Princeton
John McCarthy,
Lab, Stanford
AI
C - 1970
John Ousterhout,
UC Berkeley
Dennis Ritchie,
Bell Labs
2
Theory Part 1
Lambda Calculus
Anything which can be computed can be
computed using the lambda calculus
- Church’s Thesis
Church’s Lambda Calculus 1
• Highly theoretical basis for programming languages
• Based on “Lambda” – λ
– λ is what is used to define an “anonymous” function
– Grammar
• λargVarNameList.expression
• argVarNameList is the list of variables
• expression denotes the return value of lambda
• About State
– The only state allowed is the current list of function aliases*
• Example:
f = λx.x2
g = λx.f(x)+1
– Thus, g(x) = x2 + 1, and g(5) = 26
4
*It is said that Church was initially opposed to this idea, but it
was forced on him by his student, Alan Turing.
Church’s Lambda Calculus 2
• Two kinds of statements
– Function declarations – lambda abstraction
• Ex: λx.x+2 - a function with 1 argument that returns the
sum of the argument and 2
• Ex: λx,y.x*y - a function with two arguments that returns the
product of two given arguments
– Function applications – lambda application
• Ex: (λx.x+2)(3) – will return 5
• Ex: (λx,y.x+y)(3,5) – will return 8
– Complex applications
• (λx.x+(λx,y.x+y)(4,3)) 1 - will return 8
• If you are interested in more:
– Representation of numbers: Church Numerals
5
LISP - Lambda Calculus Realized
• Church’s proposition finally realized in an implementation called
LISP – list processor
• Uses prefix notation!
• Function add2:
– Lambda calculus: λx.x+2
– Scheme (dialect of LISP): (define (f x) (+ x 2))
• Alternatively (and closer to λ): (define f (lambda (x) (+ x 2)))
• “f is a function: takes one argument: returns the sum of the
argument and 2
– Optimizations:
• (lambda (x) (+ x 2)) and (lambda (y) (+ y 2)) equivalent
• Usage:
– (f 2) -> will evaluate to 4
– ((lambda (x) (+ x 2)) 3) -> will evaluate to 5
6
Theory Part 2
List Languages
LISP, Scheme, and Tcl are common examples of
List-centric languages
We will use Scheme to illustrate the salient
features and derivations of the List abstraction.
Pairs
• Pair – a construct with exactly 2 elements
car
cdr
• Constructing a pair
– (define a (cons 1 2)) will yield
a
1
2
• Referencing “left” and “right” elements
– (car a) will yield 1
– (cdr a) will yield 2
8
Pairs Implementation
• Pairs are implemented using λ-calculus, too!
• Pair construction is a contract “C”
– Cons: T1, T2 -> C such that:
– Car: C -> T1
– Cdr: C -> T2
• Let’s see some code…
(define cons (lambda (x y)
(define select (lambda (m)
(cond ((= m 0) x)
((= m 1) y))))
select))
9
(define (car z) (z 0))
(define (cdr z) (z 1))
Lists
• Implementation of pairs has no bearing on “type” of
the elements of the pair.
• Can an element be a pair itself? Sure!
• Lists are realized easily:
a
1
2
3
4
• (define a (cons 1 (cons 2 (cons 3 (cons 4 nil)))))
• How to retrieve values?
 1 = (car a)
 2 = (car (cdr a)) …… Built-in, called (cadr a)
10
Abstraction: Clumsiness to Grace
a
1
2
3
4
• The above list can also be declared by (Scheme):
– (define a (list 1 2 3 4))
• In Tcl:
– Declaration: set a [list 1 2 3 4]
– Accessing: The “value” of the list will be in “\$a”
– More later…
11
List Operations
• Length of a list (Scheme) - llength
(define (llength lst)
(if (null? lst)
0
(+ 1 (llength (cdr lst)))))
• Index in a list (Scheme) - lindex
(define (lindex lst idx)
(if (= 0 idx)
(car list)
(lindex (cdr lst) (- idx 1))))
• These same functions (and more) are built-in in Tcl
12
Practice Part 1
Introduction to Tcl
Constants
• In Tcl, all free constants are strings
• Upshot
– abc is the same as “abc”
– “5” is the same as 5
• <, >, == ,<= and >= compare numerically
– If any of the arguments are non-numbers, errors are
thrown
• Strings can also be compared literally:
– string compare string1 string2
14
Variables
• A Tcl variable is a C-style name, which satisfies the
regular expression:
– {[A-Za-z_][A-Za-z_0-9]*}
• Examples:
– iterator
– loopInit
– _ErrorCount76
• Non-examples:
– 78Cool
– ~notAVariable
15
Variables, Contd.
• “set” command
– Usage: set <varname> <value>
– In most other languages, <varname> = <value>
– Artifact of basis on LISP-like PLs (define varname value)
• Example:
– set a 5
– puts \$a
puts = putString – exactly like C’s
• Will print out 5
• What’s with the \$ ?
– \$<varname> is the value of a variable with name varname
• Weird…
– set a a will set the string “a” to the variable a
16
Output to screen
• puts lets the programmer send output to the screen
• Example:
– puts 5
– puts \$a
– puts “The value of variable a is \$a”
• Variables can be freely placed in a puts string
• Any way to suppress the new line?
– puts –nonewline “Enter some number:”
– Caveat: Most Operating System implementations use \n
to trigger a flush of the buffer. In most cases, after a
puts –nonewline, adding flush stdout is necessary
17
Comments
• Comments are C-shell and Perl style, and start with
a #. The rest of the line is part of the comment
• Example 1: comment on its own line
# I will now set the variable a to 5
set a 5
• Comments after a statement need a slight change
• Example 2: comment after a statement
set a 5
;# I just set the variable a to 5
• We are essentially ending the current statement
with the ; The rest of the line is the comment.
18
Math expressions
• expr is used for evaluating math expressions
• Usage: expr <expression>
• Examples:
– expr 5+3
will evaluate to 8
– expr 5*(7+3) will evaluate to 50
• General Rule of Thumb
– Anything in <expression> is exactly the same as it would
appear in C. If an expression is valid in C, then it is valid
after expr
– The only thing to remember is replacing all variable
names with \$<varname>, but this is generally not an
issue
19
Setting results of Evaluation
• [<expression>] denotes the value after evaluation of
an expression
• Example:
– set a [expr 5+6] will set the “result” of the expr to a
– set b [SomeFunction 6] will set the “return value” of
“SomeFunction” to b
• Careful!
– [set a [expr 5+6]] will result in a syntax error, because 11
is not a function!
20
Keyboard Input
• gets is a built-in Tcl command which allows for
keyboard input by user
• Example:
puts “Please enter your name: “
set userName [gets stdin]
puts “Your name is \$userName”
• Example:
puts “Enter a number: “
set input [gets stdin]
set output [Add2 \$input]
puts “\$input plus 2 is \$output”
21
Programming Assignment # 1
• Write a program that asks the user for two numbers
and prints the average of the two numbers.
• Sample Output:
22
Solution to PA # 1
23
Conditionals - if
• Syntax: if { condition } { action1 } else { action2 }
• Example:
if { \$a > 2 } {
puts “\$a is greater than 2”
} else {
puts “\$a is not greater than 2”
}
• There is no option as far as bracket style is
concerned – it is enforced like above
24
Conditionals – on the condition
• A condition is exactly as it would appear in C
• Any nonzero number is taken to be true
• Examples:
if { \$a > 5 }
if { \$a > \$b }
if { (\$a > 5) || (\$b < 3) || (\$c != \$d) }
if { \$a }
If { !\$done }
• C rule of thumb
– The condition works exactly as in C
25
Conditionals - elseif
• Used for chaining if statements
• Example:
if { \$a > 0 } {
puts “\$a is a positive number”
} elseif { \$a < 0 } {
puts “\$a is a negative number”
} else {
puts “\$a is zero”
}
26
Incr – Incrementing/Decrementing
• incr is an overloaded version of C’s ++,--,+=,-=
• Syntax: incr varName ?offset=1
• Examples:
incr i
;# Will increase i by one, the default
incr i -1
;# Will reduce i by one
incr i 3
;# Will increase i by three
incr i 0
;# Will not change I
• Common mistake:
– incr \$i 2 will cause a syntax error. We need to the variable
name to incr, not the value of the variable!
27
Loops - while
• The while loop is exactly the same as it is in C!
• Syntax: while { condition } { action }
• Example:
set i 1
while { \$i <= 10 } {
puts “On iteration \$i of 10”
incr i
}
28
Loops - for
• The for loop is exactly the same as it is in C!
• Syntax: for { initCond } { condition } { update }
• Example:
for { set i 1 } { \$i <= 10 } { incr i } {
puts “On iteration \$i of 10”
}
29
Programming Assignment # 2
• Write a program that keeps asking user for numbers till the
blank string is seen, and prints the average of the numbers:
• Sample Output:
30
Solution to PA # 2
31
Procedures
• By example:
proc Add2 { number } {
set a [expr \$number+2]
return \$a
}
• “proc” is a reserved word, and it denotes the start
of a procedure
• { number } this is a list of variables
• return \$a will return the value stored in a
• A procedure MUST be defined before being called.
– No prototypes! – Except in Itcl, more later
32
Procedures: Optional Parameters
• Optional Parameters are very easy to set up in Tcl
• By Example:
Proc Add { number { by 1 } } {
return [expr \$number+\$by]
}
• The variable by takes on a default of 1 unless
specified otherwise in the function call
Add 1
Add 1 2
Add 1 –1
33
;# Will return 2
;# Will return 3
;# Will return 0
Global Scope
• Scope works the same as in C except for one thing:
accessing global variables inside procedures
– Global variables have to be explicitly declared as such inside a
procedure
• Example:
set errorCount 0
…
proc TriggerError { errorString } {
global errorCount
puts “Error: \$errorString”
incr errorCount
}
34
Lists in Tcl
• A list is declared using the list built-in function:
• Example:
set a [list 1 2 3 4]
• The same can also be written as:
set a { 1 2 3 4 }
• Retrieving an element within a list: lindex
• lindex is 0-based, just like C
set b [lindex \$a 3] ;# b has the value 4
set b [lindex \$a end] ;# b will have value 4
set b [lindex \$b 0] ;# b will have the value 1
35
List Operations
• concat : Concatenate two lists
set b [concat [list 1 2 3 4] [list 5 6 7]]
b will be { 1 2 3 4 5 6 7 }
• lappend : Append value at the end of list – By Name
set a [list 1 2 3]
lappend a 4
– Now a will be { 1 2 3 4 }
– Note: lappend takes a list Name, not a list
• llength : Return the length of a list
– llength [list 1 2 3] will be 3
– llength [list] will be 0
• Many others… Read any Tcl book
36
Looping over lists - foreach
• Because looping over lists is a common operation,
there is a built-in construct to make this easier
• By Example:
proc PrintList { inputList } {
foreach element \$inputList {
puts \$element
}
}
• element takes on the value of each of the members
of the list*
37
*In Perl, element would be a reference to the member of the list.
Any update to element would change the list. Not so in Tcl…
Programming Assignment # 3
• Write a procedure reverseList that reverses a given
list, and returns the reversed list.
38
Solution to PA # 3
39
Arrays
• All Arrays in Tcl are one-dimensional and
associative – called a hash in other PLs
• We will see later how more dimensions can be
“induced” over single dimensional arrays
• By example:
set myArray(0) 1
set myArray(1) 2
set myArray(2) 3
puts \$myArray(0)
puts \$myArray(1)
40
Arrays, contd.
• The “keys” to arrays need not be natural numbers
• Arrays are used mainly to achieve key/data pairs
• Example:
set address(“sunil”) “cupertino”
set address(“dan”) “berkeley”
set address(“praveen”) “san jose”
puts \$address(“sunil”)
puts \$address(“dan”)
…
41
Arrays – Multiple Dimensions
• Since arrays are associative, we can form a
“composite key” by choosing a delimiter like ,
• Example:
set addresses(“sunil”,”street”) “meteor”
set addresses(“sunil”,”city”) “cupertino”
set addresses(“dan”,”street”) “hearst”
set addresses(“dan”,”city”) “berkeley”
puts \$addresses(“dan”,”street”)
…
42
Arrays – Retrieving all keys
• array names arrayName will return a list of all keys
associated with the array
• By Example:
set myArray(0) 1
set myArray(“chocolate”) “chip”
set keyList [array names myArray]
;# keyList will be { 0 chocolate }
• Common iteration technique:
foreach key [array names myArray] {
set value \$myArray(\$key)
# Now \$key and \$value might be used for any action necessary…
}
43
Arrays – One Major Drawback
• Arrays cannot be passed by value to and from other
procedures!
• Why?
– Internally, each element of an array is just another
variable. Arrays happen to be a special case where all the
variables start with the same letters, and contain a “(“
after the first name
• Give up?
– Don’t! There is pass-by-reference; we will get to it later…
44
Regular Expressions
•
•
•
•
Regular Expressions are used to match patterns
Invocation: regexp <regexp> \$var
Returns 1 if \$var matches <regexp>, 0 otherwise
Simple Sub-string Examples:
regexp {mcd} “mcdata”
regexp {cda} “mcdata”
regexp {mcdata} “mcdata”
regexp {macdata} “mcdata”
regexp {mc data} “mcdata”
45
;# 1
;# 1
;# 1
;# 0
;# 0
Regular Expressions, contd.
• Grouping
– Subsections of regular expressions are grouped using
parentheses ()
– Ex:
• regexp {(mcdata)(colorado)} mcdatacolorado ;# 1
• Multiple matching choice: Enclose in [ ]
– regexp {[0123456789]} \$var
– Will match any one of 0-9 in \$var
• regexp {[0123456789]} mcdata7
• regexp {[0123456789]} mcdata
46
;# 1
;# 0
Regular Expressions, contd.
• Range Specification
– Within [ ], ranges can be used instead of verbatim
– Ex: regexp {[A-Zu-z3-9]} …
• Quick Class Exercise
– Write a regular expression to match standard California
Vehicle Number Plates
– The first digit is a nonzero number, followed by 3 uppercase letters, followed by 3 more numbers
regexp {[1-9][A-Z][A-Z][A-Z][0-9][0-9][0-9]}
47
Regular Expressions, contd.
• Matching beginning and end of input
– Robust regular expressions are written to take everything
into account, from beginning to the end of input
– Not all situations call for such strict regular expressions,
but it useful to know how to write them nevertheless
•
•
•
•
^ matches beginning of string
\$ matches end of string
{^mcdata\$} will ONLY match “mcdata”
{^[0-9]\$} will ONLY match a string containing
exactly 1 digit
• {^[0-9]} will ONLY match a string starting with a
digit
48
Regular Expressions, contd.
• Matching “any” character
– “any” character is matched with “.”
• {^.[0-9]} will match any string with a digit as the
second character
• How to match . or [ or ^ or \$, etc.
– All regular expression characters can be escaped using \
– {^\.\[\$} will match ONLY the string “.[“
– A backslash may itself be escaped
– {\\} will match any string that contains a \
49
Regular Expressions, contd.
• Group Modifiers
•*
– Denotes at least 0 of
• Ex: {[0-9]*} means match if at least 0 digits
• Note: will always also match empty string!
•+
– Denotes at least 1 of
• Ex: {[0-9]+} means match if at least 1 digit
• Will never match empty string
•?
– Denotes either exactly 0 or exactly 1 of (or “optionally”)
• Ex: {^[0-9]?} means match if first digit is present or not
50
Programming Assignment # 4
• Update PA#2 to validate input.
• I will try to break your program!
My Solution:
{^-?([0-9])+(\.([0-9])+)?\$}
51
Passing by Reference
• Tcl has a very powerful call-by-reference model
– More appropriately called: call-by-name
• Illustrate by example: Suppose I want to write incr
proc Incr { varName { by 1 } } {
upvar \$varName var
set var [expr \$var+\$by]
return \$var
}
set i 1
Incr i
;# Will have the desired effect
• Notice that we are passing the variable to the
procedure “by name”
52
Passing by Reference, contd.
• upvar aliases a variable in the current scope to a
variable in another scope, usually the calling scope.
• upvar ?level=1 varName localVar
• When localVar is updated, the variable with the
name “varName” is updated in the scope specified.
• upvar is a very difficult concept to grasp completely
the first time around, so if you plan on passing by
reference, read Welch’s book.
53
Practice Part 2
Introduction to ITcl
Itcl = [incr Tcl]
•
•
•
•
Itcl is the Object-oriented version of Tcl
Itcl does for Tcl what C++ does for C
Provides manageability for large-scale projects
Supports multiple-inheritance, except in a
degenerate case
• Itcl manifests itself as a package that can be
brought into the standard Tcl environment
– Simply insert:
package require Itcl
namespace import -force itcl::*
55
Objects
• Objects = Data + Procedures*
• Traditionally, data structures were separate from
the procedures that acted upon them
• The Object-Oriented Paradigm (OOP) is the drive to
combine the data and procedures into one package.
Object
Data
56
Procedures
*We owe this succinct definition to Grady Booch in his
book: Object Oriented design with applications
Defining Objects - Classes
class Car {
variable year
variable color
variable doors
variable cylinders
method Drive { } {
puts “I am driving!!”
}
}
57
The object “type” is Car
year is an “attribute”
Keep track of color
Same with doors
Number of cylinders
A Car can “do” this: It
can Drive
Declaring Objects - constructor
• In order to be able to declare objects, we need to
define a special method within the class that is
called when we “create” or “construct” the object
class Car {
constructor { inYear inColor inDoors inCylinders } {
set year \$inYear
set color \$inColor
set doors \$inDoors
set cylinders \$inCylinders
}…
}
• Here, we populate the variables inside the class
with what we get during “creation”
58
Declaring Objects - Instantiation
• We can proceed to declare a Car by:
Car sunilCar 1997 Biege 4 4
• We can also perform the Drive operation on the
object just declared by:
sunilCar Drive
59
Inheritance
• What happens when we realize that we have more
attributes that are specific to say, a Toyota?
• Declare a new class and rewrite all the basic
attributes for that class over again?
• Yes and No!!
• Write a new class, but “use” the attributes already
given to us by the already existing class.
– We can do this because a Toyota is but a special case of
a Car. – “A Toyota IS A Car”
– This IS A relationship drives inheritance!
60
Base/Member Initialization
Class Toyota {
inherit Car ;
variable exhaustType
constructor {inYear inColor inDoors inCylinders inExType } {
Car::constructor \$inYear \$inColor \$inDoors \$inCylinders } {
set exhaustType \$inExType
}
}
Toyota myCar 1997 Beige 4 4 RearSingle
myCar Drive
• Can a Toyota Drive? We did not teach it!
•Sure it can! It inherited Car
61
Questions ?
• The dumbest question is the one not asked…
- Aristotle
62
Thanks !
```