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
CALLkeyword.
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:
- The keyword
RETURNS <data type>appears at the end of the first line, declaring what type of value the function gives back. - Inside the body, a
RETURN <value>statement specifies the value to send back. The function ends as soon as aRETURNruns.
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
TRUEorFALSE).
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):
LengthandWidthare the parameters.5and3are 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.
| Feature | Procedure | Function |
|---|---|---|
| Returns a value? | No | Yes |
| Keyword used to define | PROCEDURE ... ENDPROCEDURE | FUNCTION ... ENDFUNCTION |
Uses RETURNS in header? | No | Yes (RETURNS <data type>) |
Contains RETURN <value>? | No | Yes (the value to send back) |
| How it is called | With CALL keyword | Used inside an expression (no CALL) |
| Typical use | Doing something (output, save, update state) | Calculating something and giving the value back |
| Example pseudocode call | CALL 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
| Feature | Local variable | Global variable |
|---|---|---|
| Where declared | Inside a sub-program (procedure or function) | Outside any sub-program (top level) |
| Visible from | Only inside the sub-program that declared it | Anywhere in the program |
| Lifetime | Created when the sub-program starts; destroyed when it ends | Lives for the whole program run |
| Risk of accidental interference | Low: name clashes are local to the block | Higher: any code can change the value |
| Best for | Temporary calculations, loop counters, intermediate results | Shared state, configuration, totals across many sub-programs |
| Preferred style | Default choice | Use 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.