1 / 63

# Tcl Programming: Theory Practice - PowerPoint PPT Presentation

Tcl Programming: Theory & Practice. Presented By: Sunil Ramesh. Origins of Tcl. ⋋ -Calculus - 1930. LISP - 1950. TCL - 1990. Alonzo Church, Princeton. John McCarthy, AI Lab, Stanford. C - 1970. John Ousterhout, UC Berkeley. Dennis Ritchie, Bell Labs.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

### Tcl Programming:Theory & Practice

Presented By:

Sunil Ramesh

⋋-Calculus - 1930

LISP - 1950

TCL - 1990

Alonzo Church, Princeton

John McCarthy, AI Lab, Stanford

C - 1970

John Ousterhout, UC Berkeley

Dennis Ritchie, Bell Labs

### Theory Part 1Lambda Calculus

Anything which can be computed can be computed using the lambda calculus

- Church’s Thesis

• 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

• 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

*It is said that Church was initially opposed to this idea, but it was forced on him by his student, Alan Turing.

• 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

• Church’s proposition finally realized in an implementation called LISP – list processor

• Uses prefix notation!

• 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

### Theory Part 2List 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.

• 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

• 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))

(define (car z) (z 0))

(define (cdr z) (z 1))

• 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

2

3

4

1

• (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)

• 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…

a

2

3

4

1

• 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

### Practice Part 1Introduction to Tcl

• 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

• 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

• “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

• 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

• 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.

• 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

• [<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!

• gets is a built-in Tcl command which allows for keyboard input by user

• Example:

• Example:

puts “Enter a number: “

set input [gets stdin]

puts “\$input plus 2 is \$output”

• Write a program that asks the user for two numbers and prints the average of the two numbers.

• Sample Output:

• 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

• 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

• 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”

}

• 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!

• 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

}

• 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”

}

• Write a program that keeps asking user for numbers till the blank string is seen, and prints the average of the numbers:

• Sample Output:

• 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

• 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 ;# Will return 2

Add 1 2 ;# Will return 3

Add 1 –1 ;# Will return 0

• 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

}

• 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

• 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

• 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*

*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…

• Write a procedure reverseList that reverses a given list, and returns the reversed list.

• 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)

• The “keys” to arrays need not be natural numbers

• Arrays are used mainly to achieve key/data pairs

• Example:

• Since arrays are associative, we can form a “composite key” by choosing a delimiter like ,

• Example:

• 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…

}

• 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…

• 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” ;# 1

regexp {cda} “mcdata” ;# 1

regexp {mcdata} “mcdata” ;# 1

regexp {macdata} “mcdata” ;# 0

regexp {mc data} “mcdata” ;# 0

• Grouping

• Subsections of regular expressions are grouped using parentheses ()

• Ex:

• Multiple matching choice: Enclose in [ ]

• regexp {[0123456789]} \$var

• Will match any one of 0-9 in \$var

• regexp {[0123456789]} mcdata7 ;# 1

• regexp {[0123456789]} mcdata ;# 0

• 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 upper-case letters, followed by 3 more numbers

regexp {[1-9][A-Z][A-Z][A-Z][0-9][0-9][0-9]}

• 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

• 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 \

• 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

• Update PA#2 to validate input.

• I will try to break your program!

My Solution:

{^-?([0-9])+(\.([0-9])+)?\$}

• 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”

• 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.

### Practice Part 2 Introduction to ITcl

• 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::*

• 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

Procedures

Data

*We owe this succinct definition to Grady Booch in his book: Object Oriented design with applications

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

class Car {

variable year

variable color

variable doors

variable cylinders

method Drive { } {

puts “I am driving!!”

}

}

• 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”

• 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

• 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!

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

• The dumbest question is the one not asked…

- Aristotle