11.3.1 Procedures and Modular Programs
A larger program is easier to understand when it is divided into smaller, named parts. A procedure represents one of these parts: it contains a task that can be called from another location in the program.
This section uses procedures without parameters so that the focus remains on modular design, procedure definitions, calls and the movement of control. Procedure interfaces and data passing are developed on the following pages.
By the end of this section, you should be able to:
- Explain the purpose of modular programming.
- Define the term procedure.
- Identify a procedure header, body and end marker.
- Write a parameterless procedure in pseudocode.
- Write a procedure call.
- Trace control moving from the main program into a procedure and back.
- Explain the role of the main program.
- Recognise tasks that are suitable for implementation as procedures.
- Explain how procedures improve readability, testing and maintenance.
- Reuse the same procedure from several call sites.
- Place selection or repetition inside a procedure.
- Design a small program as a collection of coherent modules.
What Is Modular Programming?
Modular programming divides a larger solution into smaller sections. Each section performs a clearly defined part of the overall algorithm.
One large block
OUTPUT "EQUIPMENT CHECKOUT"
OUTPUT "1. Borrow equipment"
OUTPUT "2. Return equipment"
OUTPUT "3. View account"
OUTPUT "4. Exit"
INPUT Choice
CASE OF Choice
1 : OUTPUT "Borrow selected"
2 : OUTPUT "Return selected"
3 : OUTPUT "Account selected"
4 : OUTPUT "Closing"
ENDCASE
This small example is manageable, but a complete system could contain hundreds of statements for input, validation, menus, processing and reports.
A modular view
| Module | Responsibility |
|---|---|
ShowHeading |
Display the program title |
DisplayMenu |
Display the available choices |
BorrowEquipment |
Carry out the borrowing process |
ReturnEquipment |
Carry out the return process |
| Main program | Coordinate the order in which the modules are called |
What Is a Procedure?
A procedure is a named block of statements. Its body does not run merely because the definition exists. The procedure must be called from the main program or another procedure.
Simple procedure
PROCEDURE ShowStatus
OUTPUT "System status: ready"
ENDPROCEDURE
The procedure has been defined, but no output is produced until a call is executed.
CALL ShowStatus
The Parts of a Procedure
PROCEDURE ShowStatus
OUTPUT "System status: ready"
ENDPROCEDURE
| Part | Example | Purpose |
|---|---|---|
| Procedure header | PROCEDURE ShowStatus |
Begins the definition and identifies the procedure |
| Procedure name | ShowStatus |
Provides the identifier used by a call |
| Procedure body | OUTPUT "System status: ready" |
Contains the statements executed when called |
| End marker | ENDPROCEDURE |
Marks the end of the definition |
| Procedure call | CALL ShowStatus |
Transfers control to the procedure |
Defining and Calling a Procedure
A procedure definition and a procedure call have different roles.
Definition
PROCEDURE PrintDivider
OUTPUT "--------------------"
ENDPROCEDURE
This states what PrintDivider will do whenever it is called.
Calls
CALL PrintDivider
OUTPUT "DAILY REPORT"
CALL PrintDivider
The body of PrintDivider executes at each call site.
Resulting output
--------------------
DAILY REPORT
--------------------
CALL.
How Control Moves During a Procedure Call
Calling a procedure temporarily changes which part of the program is being executed.
PROCEDURE ShowStatus
OUTPUT "System status: ready"
ENDPROCEDURE
OUTPUT "Begin check"
CALL ShowStatus
OUTPUT "Check complete"
| Step | Current location | Action |
|---|---|---|
| 1 | Main program | Output "Begin check" |
| 2 | Main program | Reach CALL ShowStatus |
| 3 | ShowStatus |
Transfer control to the procedure body |
| 4 | ShowStatus |
Output "System status: ready" |
| 5 | Main program | Return to the statement following the call |
| 6 | Main program | Output "Check complete" |
The Role of the Main Program
The main program coordinates the overall sequence of operations. It may call procedures, use returned control to continue processing, and decide which procedure should run next.
Original example: equipment kiosk
PROCEDURE ShowHeading
OUTPUT "COMMUNITY EQUIPMENT KIOSK"
ENDPROCEDURE
PROCEDURE DisplayMenu
OUTPUT "1. Borrow equipment"
OUTPUT "2. Return equipment"
OUTPUT "3. View account"
OUTPUT "4. Exit"
ENDPROCEDURE
PROCEDURE ShowClosingMessage
OUTPUT "Session complete"
ENDPROCEDURE
CALL ShowHeading
REPEAT
CALL DisplayMenu
INPUT Choice
CASE OF Choice
1 : OUTPUT "Borrow selected"
2 : OUTPUT "Return selected"
3 : OUTPUT "Account selected"
4 : CALL ShowClosingMessage
OTHERWISE OUTPUT "Invalid choice"
ENDCASE
UNTIL Choice = 4
| Part | Responsibility |
|---|---|
ShowHeading |
Display a reusable heading |
DisplayMenu |
Display the available choices |
ShowClosingMessage |
Display the final message |
| Main program | Control the menu loop, receive the choice and select the action |
When Is a Procedure Appropriate?
A procedure is useful when a section of an algorithm represents a coherent task that can be named clearly.
| Situation | Procedure appropriate? | Reason |
|---|---|---|
| The same report heading is displayed in several places | Yes | The repeated task can be written once and called when needed |
| A menu contains many output statements | Yes | Moving the display task to a named procedure simplifies the main program |
| A distinct checkout process contains several steps | Yes | The process forms a coherent module that can be developed and tested separately |
| One simple assignment is used once | Usually unnecessary | A separate procedure may add more structure than the task requires |
| A calculation must produce a value for use in an expression | A function may be more suitable | Functions and return values are developed on a later page |
A useful design question
DisplayMenu,
PrintSummary or ResetSession?
Why Use Procedures?
| Benefit | How procedures provide it |
|---|---|
| Decomposition | A large problem is divided into smaller programming tasks |
| Readability | Meaningful procedure names communicate the purpose of program sections |
| Reduced duplication | One definition can replace repeated copies of the same statements |
| Testing | A procedure can be checked as a separate unit before the complete program is assembled |
| Debugging | An error can be investigated within the module responsible for the incorrect task |
| Maintenance | A change to a reused task can be made in one definition |
| Team development | Different modules can be designed or implemented by different programmers |
Calling the Same Procedure More Than Once
A procedure can be called from several positions in a program. Each call executes the same definition.
PROCEDURE PrintDivider
FOR Position ← 1 TO 24
OUTPUT "-" WITHOUT NEWLINE
NEXT Position
OUTPUT ""
ENDPROCEDURE
CALL PrintDivider
OUTPUT "STOCK REPORT"
CALL PrintDivider
OUTPUT "Items checked: 36"
CALL PrintDivider
The procedure is defined once and called three times.
| Without a procedure | With a procedure |
|---|---|
| The 24-character output loop is copied three times | The loop appears in one procedure definition |
| Changing the divider requires three edits | Changing the procedure updates every call |
| Repeated detail obscures the report structure | CALL PrintDivider clearly states the purpose |
Procedures Can Contain Other Control Structures
A procedure body can contain sequence, selection and repetition. Defining a procedure does not remove the need for suitable internal control structures.
Procedure containing a count-controlled loop
PROCEDURE ShowSafetyChecklist
FOR CheckNumber ← 1 TO 3
OUTPUT "Complete safety check ", CheckNumber
NEXT CheckNumber
ENDPROCEDURE
Procedure containing selection
PROCEDURE ShowConnectionStatus
IF IsConnected = TRUE
THEN
OUTPUT "Network connection available"
ELSE
OUTPUT "Working offline"
ENDIF
ENDPROCEDURE
Main-program calls
CALL ShowSafetyChecklist
CALL ShowConnectionStatus
Designing a Modular Program
Begin by identifying the major tasks in the algorithm. Each candidate procedure should have one clear responsibility.
Original scenario: community repair desk
| Required task | Possible procedure | Reason for separation |
|---|---|---|
| Display the service title | ShowHeading |
Creates a recognisable reusable presentation task |
| Display available repair categories | DisplayRepairMenu |
Removes several output statements from the main flow |
| Display collection instructions | ShowCollectionInstructions |
Groups related guidance into one named task |
| Coordinate choices and repetition | Main program | Controls the order of calls and overall session |
Possible main-program outline
CALL ShowHeading
REPEAT
CALL DisplayRepairMenu
INPUT Choice
CASE OF Choice
1 : OUTPUT "Computer repair selected"
2 : OUTPUT "Phone repair selected"
3 : CALL ShowCollectionInstructions
4 : OUTPUT "Closing service"
OTHERWISE OUTPUT "Invalid choice"
ENDCASE
UNTIL Choice = 4
Testing Procedures as Modules
A procedure can be tested before it is integrated into the complete program. A temporary call can act as a simple test harness.
Procedure under test
PROCEDURE DisplayRepairMenu
OUTPUT "1. Computer repair"
OUTPUT "2. Phone repair"
OUTPUT "3. Collection instructions"
OUTPUT "4. Exit"
ENDPROCEDURE
Temporary test harness
OUTPUT "Begin menu test"
CALL DisplayRepairMenu
OUTPUT "End menu test"
| Check | Question |
|---|---|
| Correct output | Are all menu choices displayed accurately? |
| Correct order | Do the statements run in the intended sequence? |
| Control return | Does execution continue with "End menu test"? |
| Independence | Can the module be tested without running the entire application? |
Worked Example: Modular Equipment-Check Program
The following program displays an opening panel, performs three equipment checks and then displays a completion panel.
Pseudocode
PROCEDURE PrintDivider
OUTPUT "========================"
ENDPROCEDURE
PROCEDURE ShowOpeningPanel
CALL PrintDivider
OUTPUT "EQUIPMENT SAFETY CHECK"
CALL PrintDivider
ENDPROCEDURE
PROCEDURE PerformChecks
FOR CheckNumber ← 1 TO 3
OUTPUT "Complete check ", CheckNumber
NEXT CheckNumber
ENDPROCEDURE
PROCEDURE ShowCompletionPanel
CALL PrintDivider
OUTPUT "ALL CHECKS RECORDED"
CALL PrintDivider
ENDPROCEDURE
CALL ShowOpeningPanel
CALL PerformChecks
CALL ShowCompletionPanel
Modular structure
| Module | Responsibility | Calls another procedure? |
|---|---|---|
PrintDivider |
Output one dividing line | No |
ShowOpeningPanel |
Display the opening heading | Calls PrintDivider twice |
PerformChecks |
Output the three check prompts | No |
ShowCompletionPanel |
Display the completion message | Calls PrintDivider twice |
| Main program | Call the three major stages in order | Calls all three major procedures |
Call sequence
Main program
→ ShowOpeningPanel
→ PrintDivider
← ShowOpeningPanel
→ PrintDivider
← ShowOpeningPanel
← Main program
→ PerformChecks
← Main program
→ ShowCompletionPanel
→ PrintDivider
← ShowCompletionPanel
→ PrintDivider
← ShowCompletionPanel
← Main program
Final output
========================
EQUIPMENT SAFETY CHECK
========================
Complete check 1
Complete check 2
Complete check 3
========================
ALL CHECKS RECORDED
========================
Interactive: Procedure Call Visualiser
Select a scenario and step through the call sequence. The visualiser shows the current location, the active procedure and where control will return.
Common Mistakes and Misconceptions
- Defining but not calling: the procedure body never executes.
- Starting in the first procedure definition: execution normally begins in the main program.
- Confusing a definition with a call: the definition describes the task; the call executes it.
- Returning to the start of the main program: control returns to the statement after the call.
- Continuing into the next procedure definition: after a procedure ends, control returns to its caller.
-
Forgetting
ENDPROCEDURE: the procedure boundary becomes unclear. -
Using a vague name: identifiers such as
DoStuffdo not communicate responsibility clearly. - Giving one procedure unrelated responsibilities: the module becomes difficult to understand and test.
- Creating a procedure for every single statement: too many tiny modules may obscure the overall flow.
- Repeating code instead of reusing a call: duplicated blocks create additional maintenance points.
- Assuming a procedure must return a value: returning control and returning a data value are different ideas. Functions are covered later.
- Introducing parameter details too early: this page focuses on procedure structure and modular flow; procedure interfaces are developed next.
Practice
Question 1: procedure terminology
PROCEDURE ShowWarning
OUTPUT "Battery level is low"
ENDPROCEDURE
Identify the procedure header, name, body and end marker.
Question 2: write and call a procedure
Write a procedure called ShowWelcome that outputs
"Welcome to the archive". Then write the statement that
calls it.
Question 3: trace control flow
PROCEDURE ShowNotice
OUTPUT "Maintenance begins at 18:00"
ENDPROCEDURE
OUTPUT "Opening dashboard"
CALL ShowNotice
OUTPUT "Dashboard ready"
Write the three outputs in execution order.
Question 4: identify the missing call
PROCEDURE ShowMenu
OUTPUT "1. Add"
OUTPUT "2. Edit"
OUTPUT "3. Exit"
ENDPROCEDURE
INPUT Choice
Explain why the menu is not displayed and correct the main program.
Question 5: repeated reuse
Write a procedure called PrintDivider that outputs
"----------------". Call it before and after the output
"WEEKLY SUMMARY".
Question 6: procedure containing a loop
Write a procedure called ShowSteps that uses a
count-controlled loop to output the values 1 to 5.
Question 7: choose suitable modules
A library kiosk must display a heading, display a menu, process a loan and print closing instructions. Suggest suitable procedure names and state one responsibility for each.
Question 8: explain modularity
Explain two reasons why separating a long report-generation algorithm into procedures can make development easier.
Question 9: nested procedure call
PROCEDURE PrintDivider
OUTPUT "=========="
ENDPROCEDURE
PROCEDURE ShowPanel
CALL PrintDivider
OUTPUT "CONTROL PANEL"
CALL PrintDivider
ENDPROCEDURE
OUTPUT "Start"
CALL ShowPanel
OUTPUT "End"
Trace the complete output and explain where control returns after each
call to PrintDivider.
Question 10: improve the design
OUTPUT "================"
OUTPUT "SYSTEM REPORT"
OUTPUT "================"
OUTPUT "Records: 42"
OUTPUT "================"
OUTPUT "REPORT COMPLETE"
OUTPUT "================"
Identify the repeated task and rewrite the algorithm using one reusable procedure.
Show suggested answers
Question 1
-
Header:
PROCEDURE ShowWarning -
Name:
ShowWarning -
Body:
OUTPUT "Battery level is low" -
End marker:
ENDPROCEDURE
Question 2
PROCEDURE ShowWelcome
OUTPUT "Welcome to the archive"
ENDPROCEDURE
CALL ShowWelcome
Question 3
Opening dashboard
Maintenance begins at 18:00
Dashboard ready
Question 4
The procedure is defined but never called.
CALL ShowMenu
INPUT Choice
Question 5
PROCEDURE PrintDivider
OUTPUT "----------------"
ENDPROCEDURE
CALL PrintDivider
OUTPUT "WEEKLY SUMMARY"
CALL PrintDivider
Question 6
PROCEDURE ShowSteps
FOR StepNumber ← 1 TO 5
OUTPUT StepNumber
NEXT StepNumber
ENDPROCEDURE
Question 7
-
ShowHeading: display the kiosk title. -
DisplayMenu: display the available actions. -
ProcessLoan: carry out the loan process. -
ShowClosingInstructions: display the final guidance.
Question 8
Suitable points include:
- each smaller module can be tested separately;
- meaningful procedure names make the overall flow clearer;
- repeated code can be defined once;
- changes can be made in the responsible procedure;
- different developers can work on separate modules.
Question 9
Start
==========
CONTROL PANEL
==========
End
The first divider call returns to the next statement in
ShowPanel, which outputs the panel title. The second returns
to the end of ShowPanel. Control then returns to the main
program and outputs "End".
Question 10
PROCEDURE PrintDivider
OUTPUT "================"
ENDPROCEDURE
CALL PrintDivider
OUTPUT "SYSTEM REPORT"
CALL PrintDivider
OUTPUT "Records: 42"
CALL PrintDivider
OUTPUT "REPORT COMPLETE"
CALL PrintDivider
Review
| Concept | Key idea |
|---|---|
| Modular programming | Divide a larger program into smaller, purposeful modules |
| Procedure | A named block of statements executed when called |
| Procedure header | The opening line that identifies the procedure |
| Procedure body | The statements executed during the call |
| Procedure call | The statement that transfers control into the procedure |
| Return of control | Execution resumes after the call when the procedure finishes |
| Main program | Coordinates the overall order of procedure calls and processing |
| Reuse | One definition can be called from several program locations |
| Procedure suitability | A coherent task can be named, separated, tested or reused |