Procedures and Functions

Computer Science revision notes · Cambridge (CIE) · 0984

1. Sub-programs: why they exist

A real program may be hundreds or thousands of lines long. Writing it as one giant block of code would be hard to read, hard to test, hard to debug, and almost impossible to maintain. The solution is to break the program into named blocks that each do one specific job. These named blocks are called .

Sub-programs make code:

  • Reusable: the same block can be called from many places, instead of being written out many times.
  • Easier to read: a well-named sub-program tells the reader what it does without making them read its body.
  • Easier to test: each sub-program can be tested on its own with chosen inputs.
  • Easier to maintain: a bug in one sub-program is fixed in one place, and the fix immediately applies everywhere that sub-program is called.

There are two kinds of sub-program: and .

The key difference: a function returns a value; a procedure does not.

2. Procedures

A procedure is a named block of code that performs a task without returning a value. It is invoked using the CALL keyword.

Defining a procedure

A procedure with no parameters:

PROCEDURE ProcedureName
   // statements that do the work
ENDPROCEDURE

A procedure with (values passed in):

PROCEDURE ProcedureName(Param1 : TYPE, Param2 : TYPE, ...)
   // statements that use the parameters
ENDPROCEDURE

Each parameter is named and given a data type, so the procedure knows what kind of value to expect.

Calling a procedure

Procedures are run using the CALL keyword:

CALL ProcedureName
CALL ProcedureName(Value1, Value2)

The values in brackets are called . Each argument is matched in order to the corresponding parameter in the procedure's definition.

Exam tip

Writing the line that calls a procedure

Asked for the pseudocode that uses a named procedure and passes it values, write one line: CALL, the procedure's name, then the values in brackets, separated by commas and in the order of its parameters, as in CALL ShowTotal(12, 40). One scheme gives a mark for the keyword CALL and a second for the name with the right values, so leaving out CALL costs a mark even when the rest is right. You need not write the procedure itself. A function is never called this way: it goes inside an expression, as in Total ← AddUp(12, 40).

When to use a procedure

Choose a procedure when the sub-program's job is to do something rather than to compute and return something:

  • Show a menu on screen.
  • Save data to a file.
  • Display a report.
  • Reset all the variables to a known starting state.

3. Functions

A function is a named block of code that performs a calculation and returns a value to the place it was called from. It is called directly inside an expression, not with CALL.

Defining a function

A function with no parameters:

FUNCTION FunctionName RETURNS TYPE
   // statements
   RETURN Value
ENDFUNCTION

A function with parameters:

FUNCTION FunctionName(Param1 : TYPE, Param2 : TYPE, ...) RETURNS TYPE
   // statements
   RETURN Value
ENDFUNCTION

Two extra things compared with a procedure:

  1. The keyword RETURNS <data type> appears at the end of the first line, declaring what type of value the function gives back.
  2. Inside the body, a RETURN <value> statement specifies the value to send back. The function ends as soon as a RETURN runs.

Calling a function

A function is not called with CALL. It is used inside an expression, in any place a value would normally go:

Result ← FunctionName(Value1, Value2)
OUTPUT FunctionName(5, 3)
IF FunctionName(X) > 0
   THEN
      ...
ENDIF

The expression FunctionName(...) evaluates to whatever the function returned.

When to use a function

Choose a function when the sub-program's job is to calculate and produce a value:

  • Calculate the area of a rectangle.
  • Convert a temperature from Celsius to Fahrenheit.
  • Return the largest of a list of numbers.
  • Look up a student's grade from their mark.
  • Check whether a password meets the validation rules (returning TRUE or FALSE).

4. Parameters and arguments

Both procedures and functions can take .

A parameter is a variable named in the definition of the sub-program; it holds the value passed in by the caller.

An argument is the actual value supplied at the call site.

If CalculateArea is defined with the parameters Length and Width and called as CalculateArea(5, 3):

  • Length and Width are the parameters.
  • 5 and 3 are the .

Parameters can be of any data type

PROCEDURE Greet(Name : STRING, Age : INTEGER)
   OUTPUT "Hello, ", Name, ", you are ", Age, " years old"
ENDPROCEDURE

CALL Greet("Alice", 17)

Multiple parameters in order

The order of arguments must match the order of parameters:

FUNCTION Subtract(X : INTEGER, Y : INTEGER) RETURNS INTEGER
   RETURN X - Y
ENDFUNCTION

OUTPUT Subtract(10, 3)       // 10 - 3 = 7
OUTPUT Subtract(3, 10)       // 3 - 10 = -7 (different result!)

Why parameters matter

Parameters make sub-programs reusable with different inputs. Without parameters, a procedure that calculated the area of a rectangle would only ever work for one specific length and width. With parameters, the same procedure works for any length and any width the caller chooses.

Common exam question

Why programmers use procedures, functions and parameters

Question: Explain why a programmer would use procedures and parameters, or how procedures and functions make a program easier to maintain (3–4 marks).

Asked in 2 of the 17 papers, one mark per point. For procedures and functions: they split the program into smaller, manageable parts, making it easier to read, understand and debug (a second mark); they can be re-used in this program or others and run from one line, so repeated code is cut and the program gets shorter; a well-named procedure documents what that part does; and separate procedures let a team share the work.

For parameters: they pass values from the main program into the procedure or function, the values are used inside it, and so the same sub-program can be re-used with different data. Asked together, each half is capped at three of the four marks, so include at least one parameter point. Keep to the sub-programs: comments and indentation answer a different question.

5. Procedures vs functions: side by side

A question may test this difference directly, for example by asking which kind of sub-program always returns a value.

FeatureProcedureFunction
Returns a value?NoYes
Keyword used to definePROCEDURE ... ENDPROCEDUREFUNCTION ... ENDFUNCTION
Uses RETURNS in header?NoYes (RETURNS <data type>)
Contains RETURN <value>?NoYes (the value to send back)
How it is calledWith CALL keywordUsed inside an expression (no CALL)
Typical useDoing something (output, save, update state)Calculating something and giving the value back
Example pseudocode callCALL CalculateArea(5, 3)Result ← CalculateArea(5, 3)

Quick rule of thumb

  • If the sub-program's job is to DO something, write a procedure and call it with CALL.
  • If the sub-program's job is to PRODUCE a value, write a function and use it inside an expression.

Exam tip

Describing what happens when a function is called

Asked what happens when a function is called (3 marks), give four steps in order: the function is called by its identifier; any parameters are passed to it from the main program; it carries out its task; and it returns a value to the main program. Any three earn the marks, but the returned value is what shows you are describing a function rather than a procedure, so always include it. Describe the call in words, not with CALL, which is for procedures only: a function sits inside an expression, and its returned value takes the place of the call.

6. Local and global variables (scope)

The of a variable is where in the program that variable can be seen and used.

A variable's scope depends on where it is declared. Two common scopes:

  • Local scope: the variable is visible only inside a particular sub-program or block.
  • Global scope: the variable is visible everywhere in the program.

Local variables

A local variable is one that is declared inside a (procedure or function). It only exists while that sub-program is running; once the sub-program returns, the local variable is destroyed.

Example:

PROCEDURE ShowDouble(Number : INTEGER)
   DECLARE Doubled : INTEGER
   Doubled ← Number * 2
   OUTPUT Doubled
ENDPROCEDURE

CALL ShowDouble(7)
OUTPUT Doubled       // ERROR: Doubled does not exist here

Doubled is local to ShowDouble. The main program cannot see it. As soon as the procedure ends, Doubled is forgotten.

Global variables

A global variable is one that is declared outside any sub-program, at the top level of the program. It is visible throughout the entire program, including inside sub-programs.

Example:

PROCEDURE AddPoint
   Score ← Score + 1       // can see the global Score
ENDPROCEDURE

DECLARE Score : INTEGER
Score ← 0
CALL AddPoint
CALL AddPoint
OUTPUT Score                // outputs 2

Score is declared at the top level, so any sub-program can read and update it.

Why prefer local variables when possible

Although global variables are convenient, using them too freely makes programs hard to maintain:

  • A bug that changes a global value can affect parts of the program far away from where the bug is.
  • Two sub-programs that happen to use the same variable name globally will accidentally interfere with each other.
  • Reading a program with many globals requires holding the whole program in your head at once.

Best practice: use by default, and use and return values to pass information between sub-programs. Reserve globals for genuinely shared state, such as a running total or a configuration setting.

Side-by-side comparison

FeatureLocal variableGlobal variable
Where declaredInside a sub-program (procedure or function)Outside any sub-program (top level)
Visible fromOnly inside the sub-program that declared itAnywhere in the program
LifetimeCreated when the sub-program starts; destroyed when it endsLives for the whole program run
Risk of accidental interferenceLow: name clashes are local to the blockHigher: any code can change the value
Best forTemporary calculations, loop counters, intermediate resultsShared state, configuration, totals across many sub-programs
Preferred styleDefault choiceUse sparingly

Common exam question

Matching sub-program terms to their descriptions

Question: Draw lines matching descriptions to procedure, function, parameter, local variable and global variable, or tick the term for passing a value to a procedure (1–4 marks).

Asked in 2 of the 17 papers, one mark per correct match. A sub-program that might not return a value is a procedure; one that always returns a value is a function. A value a procedure must be given when it is called is a parameter, which is also how a value is passed in; return sends a function's result back, and subroutine names either kind. A variable declared and used inside one procedure only is local; a global variable is declared outside every sub-program and is usable anywhere.

The matching version has one more term than descriptions, so place the certain ones first. The papers and schemes usually call the values passed in a call parameters too, so expect that word where these notes say argument.

Spotting scope issues

Most scope mistakes show up in three patterns. Knowing the symptoms makes them easy to fix:

  • A name appears to vanish. A variable assigned inside a procedure cannot be read by the main program afterwards. If the main program tries, it causes an error, because the variable does not exist outside the procedure. Fix by returning the value (use a function) or by writing to a genuinely shared global.
  • Two variables share a name by accident. A procedure declares a local variable whose name matches a global. Inside the procedure, writes go to the local one; the global is left untouched. The bug looks like "the total never updates". Fix by renaming one of them, or by passing the value in as a parameter.
  • A counter resets on every call. A loop variable declared inside a procedure is destroyed when the procedure ends. Calling the procedure again starts the counter from scratch. If the intent was a running total across calls, the variable belongs at the top level as a global.

A quick rule of thumb: if a value is needed in only one block, declare it locally; if several sub-programs must share it, pass it as a parameter or return it. Reach for a global only when the value really is shared state for the whole program.