Functions and Side Effects
Functions - Overview
- Functions have a return value
- All paths through a function must end with a return statement
that returns a value
- Each return must return a value of the right type
- A function can only be used in a place that is of the right type
- Disambiguation: overloaded functions can have same parameters
and different return types
Function Example
- Calculate the absolute value of the difference of params
procedure demo is
function absdiff(i, j: Integer) return Integer is
diff: Integer := i - j;
result: Natural;
begin
result := abs diff;
return result;
end demo
i: Integer := 20;
j: Integer := 10;
begin
put(absdiff(i, j));
end demo;
Functions and Overloading
- Overloading: same ____, different _____
- Both Java and Ada use a routine's signature to disambiguate overloaded functions
- Java Signature:
- Ada Signature:
- Example:
function Square(x: Integer) return Integer is ...
function Square(x: Float) return Float is ...
Parameter Modes for Functions
- Function parameters must be IN mode.
- The following code will not compile.
function sumAndPutInOrder(i, j: in out Integer) return Integer is
begin
if i < j then
swap(i, j);
end if;
return i + j;
end sumAndPutInOrder;
This makes it impossible for a function to have side effects
- However, if the parameter is a POINTER, then the object that is pointed to can
be changed, causing a side effect, even though the pointer itself is not changed.
- This is similar to a Java reference variables
Side Effects
-
Side effect: a change in the program's state caused by an expression or a function call
- Program state: values of variables or status of I/O
- Java Example: i = j++;
- Java Example: Collection add(Object o) returns true if the collection changed
- Side effects make it harder to reason about program behavior:
- harder to debug
- harder to prove that the program is correct
Side Effects and Ada Function Parameters
- Ada does not allow a function to introduce side effects through its parameters
(except via pointers).
-
For example, consider a call of the routine from above:
function sumAndPutInOrder(i, j: in out Integer) return Integer is
begin
if i < j then
swap(i, j);
end if;
return i + j;
end sumAndPutInOrder;
i: Integer := 3;
j: Integer := 2
begin
put("Average is: ");
put( sumAndPutInOrder(i, j) / 2 ); // Change i here!
new_line;
put("Smallest is");
put(i);
new_line;
end;
Side Effects and Global Variables
- Side effects also occur when a procedure or function changes a
global variable
-
Global variable: A variable is global with respect to a section of code if it is visible in the
section, but not declared in that section.
- This kind of side error is hard to find because a procedure (or
function) changes a variable that is not listed in the routine's
parameter list.
- When this can occur, it is necessary to search the
body of all relevant routines when looking for an error.
-
When there
are no side effects, then the body of a routine only needs to be
searched if it has an out parameter of interest.
- Example:
g: Integer := 1; -- Global variable
procedure putHeader is
begin
put("Something");
g := 0; -- Whoops!
end putHeader;
...
begin
put(g); -- g is correct here
putHeader;
put(g); -- g is NOT correct here
-- What happened? putHeader should NOT have changed it!