Functions and Modularization
Functions are reusable blocks of code with their own name. Learn to create functions with parameters and return values, understand scope, and apply the DRY principle.
Renato Freitas
Updated on May 5, 2026
Why functions exist
Imagine you need to calculate the BMI (Body Mass Index) of 50 different people in the same program. Without functions, you would repeat the same formula 50 times. If you discover the formula was wrong, you would need to fix it in 50 places. With a function, you write the logic once, give it a name, and call it as many times as needed.
This is the essence of the DRY principle: Don't Repeat Yourself. Duplicated code is code that needs to be maintained in multiple places. A change in one place does not propagate to the others, creating inconsistencies and bugs.
Beyond reuse, functions improve readability. A program that calls 'calculateDiscount(price, category)', 'validateTaxId(id)', and 'sendEmail(recipient, message)' is much easier to understand than a monolithic block of 200 lines with no divisions.
๐งฎ Try it yourself โ CalcSim
Want more features? Download CalcSim IA app
Anatomy of a function
A function has four components: name (the identifier by which it is called), parameters (input data, optional), body (the block of instructions that executes), and return value (the result the function gives back, optional).
Pseudocode for a function that calculates the area of a rectangle: FUNCTION calculateArea(width, height) โ RETURN width * height. To use it: area = calculateArea(5, 3). The result 15 is assigned to the variable 'area'.
Parameters are the function's 'inputs' โ values passed when it is called. Inside the function, they behave like local variables. The return value is the 'output' โ the result the function produces. A function without a return value (void) performs actions without producing a value (such as displaying text on screen).
Void functions versus functions with return values
Void functions perform actions: display data, modify global variables, save files, send emails. Their purpose is the side effect, not producing a value.
Functions with return values calculate and give back a result. They are like mathematical formulas: given a set of inputs, they produce a deterministic output. They are easier to test (you provide inputs and check whether the output is correct) and easier to reuse (the result can be passed to other functions).
A good practice is to prefer functions with return values over functions that modify global variables. This makes data flow explicit and the code more predictable.
Scope: local and global variables
Scope defines where a variable exists and can be accessed. A local variable exists only inside the function where it was created โ when the function ends, the variable ceases to exist. A global variable exists throughout the entire program and can be accessed by any function.
Excessive use of global variables is a classic problem. Any function can modify them at any time, making it hard to track who changed what. Bugs caused by unexpectedly modified global variables are notoriously difficult to find.
The general rule is to minimize variable scope: declare variables at the innermost possible level. If a variable is only used inside a function, declare it there, not in the global scope.
Modularization and thinking through problems
Modularizing means dividing a large problem into smaller, independent problems, each solved by a function. This approach is called functional decomposition.
A customer registration program can be decomposed into: validateData(), saveToDatabase(), sendConfirmationEmail(), generateReport(). Each function has a clear responsibility and can be developed, tested, and fixed independently.
This mindset of breaking problems into smaller parts applies far beyond programming. Any complex project โ a dissertation, an event, a product โ can benefit from thinking in independent modules with clear interfaces between them.
Frequently asked questions
Can a function call another function?
Yes, and this is very common and desirable. Functions that call other functions form a hierarchy of abstraction. A high-level function like 'processOrder()' might call 'validateStock()', 'calculateShipping()', and 'updateInventory()', each with its own specific responsibility.
What is a recursive function?
A function that calls itself. It is useful for naturally recursive problems such as calculating factorials, traversing trees, and divide-and-conquer. Every recursive function needs a stopping condition (base case) to avoid an infinite loop.
How many lines should a function have?
There is no absolute rule, but functions shorter than 20โ30 lines tend to be easier to understand and test. If a function is growing large, it is probably doing more than one thing and can be split into smaller functions.
What is function overloading?
Overloading is when multiple functions share the same name but have different parameters. The compiler chooses which version to call based on the types of the arguments. For example, 'add(int, int)' and 'add(float, float)' can be two distinct functions with the same name.
Was this article helpful?
Rate with stars to help us improve the content.
Sign in to rate this article.
Still have questions?
The AI Professor explains step by step
Ask a question in natural language and get a personalised explanation about Programming Logic โ or any other topic.
Prefer to solve it on your phone?
Download the free app โKeep learning