Module 0073: Local variables and parameters

Tak Auyeung, Ph.D.

November 25, 2018

Contents

1 About this module
2 Local variable
 2.1 The concept
 2.2 A simple example
 2.3 Tracing a local variable
3 Parameters
 3.1 By value
  3.1.1 The concept
  3.1.2 An example
  3.1.3 Trace
 3.2 By reference
  3.2.1 The concept
  3.2.2 An example
  3.2.3 Trace

1 About this module

2 Local variable

We are already discussed variables in module 0012. In this module, we will talk about local variables.

2.1 The concept

A local variable is visible only from within the subroutine that contains it. Because of this property, multiple subroutines can contain local variables of the same name.

This property may not seem very important for now. However, when you need to handle programs with 100s or 1000s of thousands of lines, the last thing you want to worry is whether a variable is shared between two subroutines.

In terms of notation, we can define local variables (in pseudocode) just by saying “local varname”, where varname should be replaced by the name of an actual variable.

2.2 A simple example

Here is a simple example:


Listing 1: Subroutines with local variables
1define sub sub1 
2  local i 
3  i0  
4  while i<2 do  
5    print "x"  
6    ii+1  
7  end while 
8end define sub  
9 
10define sub sub2 
11  local i 
12  i0  
13  while i<2 do  
14    invoke sub1  
15    ii+1  
16  end while 
17end define sub  
18 
19invoke sub2  
20

Because local variables are local to to each subroutine, the output of this program is “xxxx”. However, if the variable “i” is not local to each subroutine, then what will the program output?

2.3 Tracing a local variable

Tracing a program with local variable is not too different from a program with subroutines. The main difference is that instead of just creating a column for the return line number, we also create a column for the local variable(s). The trace of 1 is in table 1.


A B C DE F








line #comments

annotation








19 retline#i

the invocation of sub2 and the allocation of columns

19 ?

note how a local variable always starts with an unknown value








12 0

local variable i is initialized








13 i < 2 is true

i refers to column D, the right-most column with a label of the name of the referenced variable








14 retline#i

allocate columns for the invocation of sub1

15 ?

note there is another column allocated with a local i








3 0

this i refers to the rightmost column labeled i








4 i < 2 is true

this i refers to column F, the rightmost column in use that is labeled i








5








6 1








4 i < 2 is true








5








6 2








4 i < 2 is false








8 retline#i

retrieve return line number, deallocate columns allocated to the returning subroutine








15 1

i refers to the rightmost column in use that is labeled i








13 i < 2 is true








14 retline#i

columns are reallocated for the second invocation of sub1

15 ?

note how i is unknown again








3 0








4 i < 2 is true








5








6 1








4 i < 2 is true








5








6 2








4 i < 2 is false








8 retline#i

deallocate columns of this invocation to use retline# to continue execution in caller








15 2








13 i < 2 is false








17 retline#i

deallocate columns of invoking sub2 and use retline# to continue execution in caller








20

end of execution


Table 1: Trace of algorithm 1.

Note that local variables do not start with any particular value. A local variable must be initialized before it is read.

3 Parameters

A parameter is a method to pass data to a subroutine. A subroutine may include parameters. When such a subroutine is invoked, each parameter must be “filled” by an argument. An argument is supplied by the invoking code. There are two types of links between an argument and its parameters.

3.1 By value

3.1.1 The concept

One type of parameter is called “pass by value” parameters. Such a parameter is almost like a local variable, except the initial value of such a local variable is specified by the matching argument.

Other than that, a by-value parameter behaves much like a local variable. It can only be seen inside the subroutine that defines it, it is allocated storage only when a subroutine is invoked, and it loses storage as soon as the subroutine returns.

The notation in our pseudocode defines a parameter by the keywords “byval param-name”.

3.1.2 An example

Let us modify algorithm 1 to use parameters in sub1. We will eliminate sub2 and just invoke sub1 multiple times from the “main program”.


Listing 2: Subroutine with a parameter
1define sub sub1 
2  byval n 
3  local i 
4  i0  
5  while i<n do  
6    print "x"  
7    ii+1  
8  end while 
9end define sub  
10 
11invoke sub1 2n  
12invoke sub1 1n  
13

In this example, we use parameter n in sub1 to specify how many “x” to print. Note that we use n to specify the end value of i in the loop.

Note that when we invoke sub1, we need to specify what value specifies the initial value of a parameters. This is why we have the notation 2 n on line 11 to specify that parameter n should start with an initial value of 2. The use of the right arrow ( ) indicates that information is flowing only one way (to parameter n).

Note that the left hand side of the symbol is specified by the invoking code, whereas the right hand side of the symbol specifies a parameter of the called subroutine.

3.1.3 Trace

To trace a subroutine with a parameter is not much different from tracing a subroutine with a local variable. The main difference is that a by-value parameter starts with a value specified by the invoking statement, whereas a local variable does not start with any particular value.

The trace of algorithm 2 is listed in table 2.


line #comments

annotation







11 retline#ni

invocation of sub1 allocates columns for retline#, the parameters and local variables of the subroutine

12 2?

the initial value of a by value parameter comes from the invoke statement, but a local variable starts with an unknown value







4 0

i is now initialized by sub1 to 0







5 i < n is true

comparing a local variable to a parameter







6

print “x”







7 1

increment i







5 i < n is true







6

print “x”







7 2

increment i







5 i < n is false







9 retline#ni

deallocate all the columns allocated to this invocation, but use the retline# column to know which line to continue execution in the caller







12 retline#ni

reallocate columns for the second invocation of sub1

13 1?







4 0

i is now initialized by sub1 to 0







5 i < n is true







6

print “x”







7 1

increment i







5 i < n is false







9 retline#ni

deallocate all the columns for this invocation and use retline# to know where to continue execution







13

done


Table 2: The trace of algorithm 2.

3.2 By reference

3.2.1 The concept

Passing parameters by reference is a little bit tricky. Instead of using the technical term “by reference”, let us use the less formal term “by alias”.

A parameter is that passed by reference (alias) is, well, an alias of something else. This means when we read from such a parameter, we are reading from something else. Similarly, when we write to such a parameter, we are writing to something else.

This make by-reference parameters useful for modifying variables that belong to someone else. In other words, it make the effect of a subroutine cross the “end define sub” boundary.

The notation of such a parameter in our pseudocode is “byref param-name”.

3.2.2 An example

Let us consider a relatively simple example. We are writing a subroutine to initialize a variable to 0. Algorithm 3 is an algorithm based on this subroutine.


Listing 3: Subroutine with a by-reference parameter
1define sub init0 
2  byref x 
3  x0  
4end define sub  
5 
6invoke init0 mainvarx  
7

In this example, mainvar is a variable that is local to the main program. This means this variable is not visible from the subroutine. When we invoke init0, we need to specify that argument mainvar specifies what parameter x is an alias of. The use of the double arrow ( ) indicates that information can flow both ways. Whatever happens to x happens to mainvar, but any attempt to read x is actually reading mainvar.

Note that the left hand side of the symbol is specified by the invoking code, whereas the right hand side of the symbol specifies a parameter of the called subroutine.

3.2.3 Trace

The trace of algorithm 3 is short. However, it is deceptively simple because the concept of passing by reference is very different from the concepts of local variables and passing by value.

Table 3 is a trace of algorithm 3.


A B C D

annotation






line #mainvar

mainvar is a global variable it exists from the beginning






pre ?

a global variable starts with an unknown value






6 retline#x

allocate one column for retline#, and one for the parameter

7 ref to col B

note a byref parameter is a reference to a column where the referred item is






3 0

the assignment does not change parameter x, but it changes column that the parameter refers to






4 retline#x

now we deallocate the columns. The effect on column B, however, is persistent.






7

we are all done!


Table 3: The trace of algorithm 3.