Methods and Parameters

 

A method bundles up a sequence of useful instructions and assigns it a name. Methods are an excellent way for software components to communicate.

 

Most programming languages provide two types of methods:

 

 

Function methods

 

A function method takes any number of parameters but returns a single value. A call on a function method appears as part of an expression. For example:

 

z = largest(x, y);

 

Here is the coding (in Java) for this method:

 

int largest(int n, int m) {

    if (n > m) {

        return n;

    }

    else {

        return m;

    }

}

 

The method begins with the declaration of the return type (int in this example), which also identifies the method as a function method.

 

A function method asks a question – what is the value of something? Information is passed to the function via its parameters and the answer is returned as the value of the function.

 

Procedure methods

 

A procedure method has parameters but does not return a value. A call on a procedure method appears as a distinct statement. For example:

 

display(x);

 

A procedure method carries out an action – some task is carried out. Information is passed to a method via its parameters, but there is no need for a value to be returned.

 

Object Oriented programming.

 

How is parameter passing different in OOP? The answer is: not very much. Look at this method call:

 

setText(myTextBox, "hello);

 

which is a method call in a non-OO situation. In OOP, we simply remove one of the parameters and make it a prefix:

 

myTextBox.setText("hello");

 

Side Effects

 

Ideally, communication between a caller and a method is as clear and simple as possible. The best way of achieving this is to ensure that all the communication takes place by means of the parameters. This way the communication is obvious.

 

By contrast, a poor alternative is the use of side effects. A side effect is any communication that takes place other than via parameters. This can happen if the method has direct access to information in the calling component. For example:

 

int l;

largest(x, y);

 

int largest(int n, int m) {

    if (n > m) {

        l = n;

    }

    else {

        l = m;

    }

}

 

The problem here is that neither inspection of the method call or the method header reveals the side effect. The programming language can eradicate this type of side effect by enforcing scope rules.

 

Examples of side effects carried out by a method are:

 

 

Clearly doing these things is vital in most software! So performing side effects in mainstream software is absolutely vital. However, in functional programming, side effects are not possible - functional programming constitutes the purist kind of programming. Functional programming exhibits referential transparency. This means that whenever and wherever a method is called, it always has the same effect. Clearly this is impractical in (normal) imperative programming.

 

Parameters

 

It is common to distinguish two types of parameter

 

 

In call by value, a copy of the value is passed as the parameter to the method. This means that the method can use the value, but cannot change the value back in the caller. Thus, the scheme is very safe.

 

There can be a performance problem with call by value, because time and space are required to copy the value in main memory. This is worse if large objects such as arrays are passed as parameters. This is also true of a return value. Thus some programming languages (e.g. Fortran, which is often used for processing arrays) do not provide call by value.

 

In call by reference, the parameter is a pointer to some data. Thus the method can choose to change the value of the data in the calling component. This can be dangerous if the user does not expect it.

 

Some languages enable the programmer to specify the type of the parameter as either ref or value. This improves clarity and enables the compiler to check for compatible use. Here, for example, is a method that changes the values of its parameters:

 

void swap(ref int x, ref int y) {

    int temp;

 

    temp = x;

    x = y;

    y = temp;

}

 

Java confuses the picture. All parameters are passed by value. But there are two types of entities in Java – primitive entities such as int (which are not objects) and proper objects. When a primitive entity I passed, its value cannot be changed. When an object is passed as a parameter, a reference (pointer) to the object is passed. The pointer itself cannot be changed, but the data items within the object pointed to can.

 

Some languages (e.g. C++) allow the program to change pointers that are passed as parameters. So a method can change the value of the pointer so as to point to some other object. This, again, can be dangerous.

 

Arguably, thinking about pointers is really a low-level view of programming. A different approach is to label parameters as in, out or in-out as follows:

 

in – a value is passed to a method. The method can use the value but cannot change the value

out – this parameter is used to return a new value to the caller. The method can assign a value, but cannot use its value.

in-out – the value of the parameter can be used and its value can be changed.

 

STQ

Write the header of a method that finds that sum of its first two integer parameters, providing the answer as a third parameter

Answer

void sum(in int x, in int, y, out int answer)

End

 

The purist approach

 

Following the influence of functional programming, it is possible to adopt a very pure attitude to methods and parameters. In functional programming, all parameters are passed as values (which therefore cannot be changed by the method). Any information to be passed back to the caller is communicated as a return value. This prevents any method from changing data in the caller.

 

Following this scheme, a purist approach is:

 

 

 

Thus there is a clear separation of roles between function and procedure methods.

 

It is not always easy to adopt this strategy, but usually it is. An example where it is not possible is a method to interchange the value of two parameters.