Home SEO Tools HTML Escape Tool Character Counter Guest post

Procedures in Tcl programming

0 comments


Procedures in Tcl

In this part of the tutorial, we will cover Tcl procedures.
A procedure is a code block containing a series of commands. Procedures are called functions in some programming languages. It is a good programming practice that procedures do only one specific task. Procedures bring modularity to programs. Proper use of procedures bring the following advantages:
  • Reducing duplication of code
  • Decomposing complex problems into simpler pieces
  • Improving clarity of the code
  • Reuse of code
  • Information hiding
There are two basic types of procedures. Built-in procedures and user defined ones. The built-in procedures are part of the Tcl core language. Examples are: rand(), sin() or exp(). The user defined functions are functions created with the proc keyword.
The term procedures and commands are often used interchangeably. In other words, the proc keyword is used to create new Tcl commands.
We start with a simple example.
#!/usr/bin/tclsh

proc tclver {} {

set v [info tclversion]
puts "this is tcl version $v"
}

tclver
In this script, we create a simple tclver procedure. The procedure prints the version of Tcl language.
proc tclver {} {
The new procedure is created with the proc command. The {} characters tell us, that the procedure takes no arguments.
    {

set v [info tclversion]
puts "this is tcl version $v"
}
This is the body of the tclver procedure. It is executed, when we execute the tclver command. The body of the command lies between the curly brackets.
tclver
The procedure is called by specifying its name.
$ ./version.tcl 
this is tcl version 8.5
Sample output.

Procedure arguments

An argument is a value passed to the procedure. Procedures can take one or more arguments. If procedures work with data, we must pass the data to the procedures.
In the following example, we have a procedure which takes one argument.
#!/usr/bin/tclsh

proc ftc {f} {

return [expr $f * 9 / 5 + 32]
}

puts [ftc 100]
puts [ftc 0]
puts [ftc 30]
We create a ftc procedure, which transforms fahrenheit temperature to celsius temperature.
proc ftc {f} {
The procedure takes one parameter. Its name f will be used in the body of the procedure.
return [expr $f * 9 / 5 + 32]
We compute the value of the celsius temperature. The returncommand returns the value to the caller. If the procedure doesn't execute an explicit return, then its return value is the value of the last command executed in the procedure's body.
puts [ftc 100]
The ftc procedure is executed. It takes 100 as a parameter. It is the temperature in fahrenheit. The returned value is used by the putscommand, which prints it to the console.
$ ./fahrenheit.tcl
212
32
86
Output.

Next we will have a procedure, which takes two arguments.
#!/usr/bin/tclsh

proc maximum {x y} {

if {$x > $y} {

return $x
} else {

return $y
}
}

set a 23
set b 32

set val [maximum $a $b]
puts "The max of $a, $b is $val"
We have a maximum procedure, which returns the maximum of two values.
proc maximum {x y} {
The method takes two arguments.
if {$x > $y} {

return $x
} else {

return $y
}
Here we compute which number is greater.
set a 23
set b 32
We define two variables, which are to be compared.
set val [maximum $a $b]
We calculate the maximum of the two variables.
$ ./maximum.tcl
The max of 23, 32 is 32
Output.

Variable number of arguments

A procedure can take and process variable number of arguments. For this we use the special args argument.
#!/usr/bin/tclsh

proc sum {args} {

set s 0

foreach arg $args {

incr s $arg
}

return $s
}

puts [sum 1 2 3 4]
puts [sum 1 2]
puts [sum 4]
We define a sum procedure which adds up all its arguments.
proc sum {args} {
The sum procedure has a special args argument. It has a list of all values passed to the procedure.
foreach arg $args {

incr s $arg
}
We go through the list and calculate the sum.
puts [sum 1 2 3 4]
puts [sum 1 2]
puts [sum 4]
We call the sum procedure three times. In the first case, it takes 4 arguments, in the second case 2, in the last case one. We call the same method.
$ ./variable.tcl
10
3
4
Output.

Implicit arguments

The arguments in Tcl procedures may have implicit values. An implicit value is used, if no explicit value is provided.
#!/usr/bin/tclsh

proc power {a {b 2}} {

if {$b == 2} {
return [expr $a * $a]
}

set value 1

for {set i 0} {$i<$b} {incr i} {

set value [expr $value * $a]
}

return $value
}

set v1 [power 5]
set v2 [power 5 4]

puts "5^2 is $v1"
puts "5^4 is $v2"
Here we create a power procedure. The procedure has one argument with an implicit value. We can call the procedure with one or two arguments.
proc power {a {b 2}} {
The second argument b, has an implicit value 2. If we provide only one argument, the power procedure then returns the value of a to the power 2.
set v1 [power 5]
set v2 [power 5 4]
We call the power procedure with one and two arguments. The first line computes the value of 5 to the power 2. The second line value of 5 to the power 4.
$ ./implicit.tcl
5^2 is 25
5^4 is 625
Output.

Recursion

Recursion, in mathematics and computer science, is a way of defining functions in which the function being defined is applied within its own definition. In other words, a recursive function calls itself to do its job. Recursion is a widely used approach to solve many programming tasks.
Recursion calls have a limit in Tcl. There cannot be more than 1000 recursion calls.
A typical example of recursion is calculation of the factorial. Factorial n!, is the product of all positive integers less than or equal to n.
#!/usr/bin/tclsh

proc factorial n {

if {$n==0} {

return 1
} else {

return [expr $n * [factorial [expr $n - 1]]]
}
}

# Stack limit between 800 and 1000 levels

puts [factorial 4]
puts [factorial 10]
puts [factorial 18]
In this code example, we calculate the factorial of three numbers.
return [expr $n * [factorial [expr $n - 1]]]
Inside the body of the factorial procedure, we call the factorial procedure with a modified argument. The procedure calls itself.
$ ./recursion.tcl
24
3628800
6402373705728000
These are the results. If we tried to compute the factorial of 100, we would receive "too many nested evaluations" error.

Scope

A variable declared inside a procedure has a procedure scope. The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name. A variable which is declared inside a procedure has a procedure scope. It is also called a local scope. The variable is valid only in this particular procedure.
#!/usr/bin/tclsh

proc test {} {

puts "inside procedure"
#puts "x is $x"
set x 4
puts "x is $x"
}

set x 1

puts "outside procedure"
puts "x is $x"

test

puts "outside procedure"
puts "x is $x"
In the preceding example, we have an x variable defined outside and inside of the test procedure.
set x 4
puts "x is $x"
Inside the test procedure, we define an x variable. The variable has local scope. It is valid only inside this procedure.
set x 1

puts "outside procedure"
puts "x is $x"
We define an x variable outside the procedure. It has a global scope. The variables do not conflict, because they have different scopes.
$ ./scope.tcl
outside procedure
x is 1
inside procedure
x is 4
outside procedure
x is 1
Output.

It is possible to change the global variable inside a procedure.
#!/usr/bin/tclsh

proc test {} {

upvar x y
puts "inside procedure"
puts "y is $y"
set y 4
puts "y is $y"
}

set x 1

puts "outside procedure"
puts "x is $x"

test

puts "outside procedure"
puts "x is $x"
We define a global x variable. We change the variable inside the test procedure.
upvar x y
We refer to the global x variable by the name y with the upvar command.
set y 4
We assign a value to the local y variable and also change the value of the global x variable.
$ ./scope2.tcl
outside procedure
x is 1
inside procedure
y is 1
y is 4
outside procedure
x is 4
From the output we can see, that the test procedure has changed the x variable.

With the global command, we can refer to global variables from procedures.
#!/usr/bin/tclsh

proc test {} {

global x
puts "inside test procedure x is $x"

proc nested {} {
global x
puts "inside nested x is $x"
}
}

set x 1

test
nested

puts "outside x is $x"
In the above example, we have a test procedure and a nested procedure defined within the test procedure. We refer to the global x variable from both procedures.
global x 
puts "inside test procedure x is $x"
With the global command, we refer to the global x variable, defined outside the test procedure.
proc nested {} {
global x
puts "inside nested x is $x"
}
It is possible to create nested procedures. These are procedures defined inside other procedures. We refer to the global x variable with the global command.
test
nested
We call the test procedure and its nested procedure.
$ ./scope3.tcl
inside test procedure x is 1
inside nested x is 1
outside x is 1
Output.
In this part of the Tcl tutorial, we covered Tcl procedures.

Do you like this Tutorial? Please link back to this article by copying one of the codes below.

URL: HTML link code: BB (forum) link code:

No comments:

FAQs | Privacy Policy | Contact | | Advertise | Donate