A function, in programming, is a named block of instructions defined once and reused by calling it by its name. It can take data in as input (the parameters) and return a result as output (the return value). Splitting a program into functions makes it readable, reusable and testable: instead of one long sequence of instructions, you read a series of blocks with a clear role.
Not to be confused with a function in the sense of functional analysis (FP / FS / FC), which describes a service the product delivers, not a block of code.
What is it for?
Three benefits, and they add up as soon as a program grows:
- Factoring out — writing once what serves several times, instead of copying and pasting (and having to fix every copy when a bug shows up).
- Naming an intent.
lireTemperature()reads better than a dozen conversion lines drowned in the loop. - Isolating. A function is tested and debugged on its own, which matters once the system gets large.
In embedded work it is also the basic structure: every Arduino program lives in two functions, setup() (start-up settings) and loop() (main loop), and the rest of the firmware is organised into functions with a clear role (lireCapteur(), commanderMoteur()).
How to write a function
A function is defined by a return type, a name, parameters between brackets, and a body between braces. return sends the output value back. The void type means there is no return value.
float moyenne(int a, int b) { // return type · name · parameters
return (a + b) / 2.0; // value returned
}It is then called by its name, with its arguments passed to it:
float m = moyenne(10, 20); // m is 15.0Variables declared inside a function only exist while it runs (their scope is local): that point, central in embedded work, is detailed in local and global variables.
Pitfalls
Confusing defining and calling. Writing a function does not run it: as long as it is never called by its name, its code never runs.
Forgetting the return value. A function that is not void must return a value consistent with its type, on every execution path.
A function that does too much. A function meant to do everything ends up as unreadable as the code it was supposed to clarify. One function, one intent.