Subroutines: Procedures and Functions

Imagine you are writing a program for a school prize-giving. Every single pupil needs a cheery welcome message, a line of decorative stars, and their name in capitals. There are 200 pupils. Are you really going to copy-paste those three lines 200 times? If you later decide the welcome should say "Congratulations" instead of "Well done", you would have to find and fix all 200 copies — and miss a few.

There is a much better way. You write the welcome routine once, give it a name, and then just say that name whenever you want it to happen. That named, reusable block of code is called a subroutine, and using it by name is called calling it.

Nearly every language has them; you have already been using one every time you write console.log(...) — that is a subroutine someone else wrote for you.

Your first subroutine: greet

Here is the whole idea in miniature. We define a subroutine called greet, and then call it three times. Notice how the greeting is written out only once, but happens three times. Press Run:

function greet(): void { // DEFINE the subroutine (this alone prints nothing) console.log("Welcome to the prize-giving!"); console.log("★ ★ ★ ★ ★"); } greet(); // CALL it — now it runs greet(); // call it again greet(); // ...and again

The word function begins the definition, then comes the name greet, then the body in curly braces { } — the actual work. Writing that down does not run it. The program only springs to life at the three greet() calls near the bottom. Each call jumps up to the body, runs every line, then comes back to carry on where it left off.

Two flavours: procedures and functions

Subroutines come in two kinds, and the difference is simple but important:

Think of the difference like asking a helper to do a job. A procedure is "please tidy the classroom" — they do it, and that's that. A function is "please count the chairs" — they do the work and come back and tell you the number, which you can then write down or use.

Very nearly, and that's where the name comes from. In maths, f(x) = x^2 takes an input and gives back an output — put in 3, get out 9. A programming function does the same: it takes some input, works out an answer, and returns it. The big extra in programming is the procedure — a subroutine that runs steps but returns nothing at all, which has no real equivalent in a maths formula. Different exam boards sometimes blur "function" and "procedure" together and just say "subroutine"; the safe rule to remember is a function returns a value, a procedure does not.

A function that returns a value: square

Here is a tiny function. It works out a number squared and hands the answer back using the keyword return. Because it returns something, we can catch that value — store it in a variable, or drop it straight into a console.log:

function square(n: number): number { // : number after the ) means it returns a number return n * n; // hand the answer back to the caller } const a = square(5); // catch the returned value in a variable console.log("5 squared is", a); console.log("9 squared is", square(9)); // ...or use it straight away const total = square(3) + square(4); // returned values are just numbers — do maths with them console.log("3² + 4² =", total);

See how square(5) behaves like the number 25 itself: you can store it, print it, or add it to another value. That is the whole point of returning — the answer flows out of the function and back into your program. A procedure like greet can't be used like this, because it gives nothing back.

Naming a piece of a problem: areaOfRectangle

Subroutines aren't only about saving typing — they let you break a big problem into named pieces. A good name is like a label on a box: you can use "work out the area of a rectangle" without re-reading how it's done every time. Here areaOfRectangle is a function that returns an area, and we reuse it for several rooms:

function areaOfRectangle(width: number, height: number): number { return width * height; } const kitchen = areaOfRectangle(4, 3); const hallway = areaOfRectangle(6, 2); const bedroom = areaOfRectangle(5, 5); console.log("Kitchen area:", kitchen); console.log("Hallway area:", hallway); console.log("Bedroom area:", bedroom); console.log("Total floor area:", kitchen + hallway + bedroom);

The reader of your program sees areaOfRectangle(4, 3) and instantly understands the intent — far clearer than a bare 4 * 3 buried in the middle of a long calculation. And if the formula ever needed changing, there is one place to change it.

(Here width and height are parameters — the inputs a subroutine is given — and there is a whole page about passing inputs and getting outputs: parameters and return values. On this page we're keeping the focus on the big idea of the subroutine itself.)

Why subroutines matter

Once you have subroutines, three good things follow — worth learning by name for your exam:

Look back at greet: if the head teacher wants a different message next year, you edit the body once and all three calls (or all 200!) change together. That single-place edit is the everyday superpower subroutines give you.

Two classic beginner slip-ups, both about the difference between defining a subroutine and calling it.

1. Defining it is not the same as running it. Writing a function block only teaches the computer what to do — it doesn't do it. Nothing happens until you call the subroutine by name with its brackets. This program prints nothing at all, because greet is defined but never called:

function greet(): void { console.log("Hello!"); } // ...and that's it. No greet(); anywhere, so nothing is ever printed.

2. A function's returned value must be used, or it's lost. When a function returns a value, that value floats back to the call — and if you don't catch it (store it in a variable or print it), it vanishes. This line quietly throws the answer away:

square(5); // computes 25, then discards it — pointless! const a = square(5); // GOOD: store it console.log(square(5)); // GOOD: print it

The habit to build: after a function call, ask yourself "where does the returned value go?" If the answer is "nowhere", you've probably made a mistake.