A parameter is a named variable declared in a function definition that receives a value when the function is called. In programming, parameters form the input side of a function’s interface: they state what information the function needs, and often of what type, so that the same code can operate on different data each time it runs.
Parameters are closely paired with arguments. The parameter is the placeholder in the definition, while the argument is the actual value supplied in a particular call. In def area(width, height), the names width and height are parameters; in the call area(3, 4), the values 3 and 4 are arguments. Many developers use the words loosely, but the distinction matters when reading language specifications and error messages.
How parameters receive values
When a function is called, the language runtime creates a new scope for that call and binds each parameter name to the corresponding argument. The parameter then behaves like a local variable: it exists only during that execution of the function and disappears when the function returns, unless something such as a closure keeps it alive.
How the binding happens is defined by the language’s evaluation strategy. This determines whether the function receives an independent copy of the data, a reference to the caller’s data, or something in between. Misunderstanding the strategy is one of the most common sources of bugs for programmers who move between languages.
| Strategy | What the function receives | Can it change the caller’s variable | Typical languages |
|---|---|---|---|
| Pass by value | A copy of the value | No | C, Go for basic types |
| Pass by reference | An alias for the caller’s variable | Yes | C++ references, C# ref, PHP with & |
| Pass by sharing | A copy of a reference to an object | No, but it can mutate the object | Python, Java objects, JavaScript |
| Pass by pointer | A copy of a memory address | Through dereferencing | C, C++, Go |
| Pass by move | Ownership of the value | Caller can no longer use it | Rust |
The pass-by-sharing model causes the most confusion. In Python or JavaScript, appending to a list received as a parameter changes the caller’s list, because both names refer to the same object. Assigning a new list to the parameter, however, only rebinds the local name and leaves the caller untouched.
Kinds of parameters
Modern languages offer several kinds of parameters that make interfaces more flexible and self-documenting. The table summarizes the most common forms.
| Kind | Example | Purpose |
|---|---|---|
| Positional parameter | def move(x, y) | Matched to arguments by order |
| Default parameter | def connect(timeout=30) | Optional, uses a preset value |
| Keyword or named parameter | send(to="ops", retry=True) | Matched by name, clearer calls |
| Variadic parameter | def total(*values) | Accepts any number of arguments |
| Output parameter | out int result in C# | Returns extra data through the parameter |
| Generic type parameter | List<T> | Makes a function or type work for many types |
Default values deserve care. In Python, a default such as an empty list is created once when the function is defined, not on every call, so modifications persist between calls. The common remedy is to use None as the default and create a new list inside the function.
Parameters compared with related concepts
A parameter is one part of the contract between a function and its callers. The neighboring concepts below cover the other parts of that contract and of program state.
| Concept | Role | Relationship to parameters |
|---|---|---|
| Parameter | Named input in the definition | The subject of this comparison |
| Argument | Actual value in a call | Bound to a parameter at call time |
| Variable | Named storage for a value | A parameter is a special local variable |
| Return value | Output sent back to the caller | The output counterpart of parameters |
| Global variable | State visible across functions | Hidden input that bypasses parameters |
| Configuration parameter | Setting read by a whole program | Same word, different level of design |
Passing data through parameters instead of global variables makes a function easier to test and reuse, because everything it depends on is visible in its signature. This principle underlies pure functions, whose result depends only on their parameters, and dependency injection, where collaborators are passed in rather than looked up.
Designing good parameter lists
The parameter list is the most visible part of a function’s design, and small decisions here affect readability for years. Experienced developers follow a few consistent rules.
- Keep the count small. Functions with more than three or four parameters become hard to call correctly; grouping related values into an object or record usually helps.
- Avoid boolean flags that switch behavior, such as
render(true). Two clearly named functions or a named option are easier to read. - Put required parameters first, followed by optional ones with sensible defaults.
- Use precise names and types. A parameter called timeoutSeconds prevents unit errors that a parameter called t invites.
- Validate parameters at boundaries, such as public interfaces, and report invalid input with a clear exception.
Common mistakes
Errors related to parameters are usually silent at first, because the code runs but uses the wrong data.
- Swapping arguments of the same type, such as width and height, which the compiler cannot detect.
- Mutating a received object unexpectedly, which changes data the caller still relies on.
- Shadowing, when a parameter has the same name as an outer variable and hides it inside the function.
- Relying on evaluation order of arguments, which some languages, such as C and C++, do not fully define.
The short version
A parameter is a blank space in a set of instructions that gets filled in each time the instructions are used. A recipe might say “bake for a number of minutes”. The number of minutes is the parameter. Each time you cook, you fill in the actual number.
Functions in a program work the same way. They name the information they need in their definition. Each time the program uses the function, it supplies real values for those names.
Where it makes a difference
A developer maintains a function that sends reminder emails. Its original signature is send_reminder(user, days, urgent), and one call reads send_reminder(user, 7, True). A colleague later misreads the call and passes the arguments as send_reminder(user, True, 7), which the dynamic language accepts without complaint, and customers receive reminders scheduled for the wrong day.
The developer redesigns the signature with keyword-only parameters and type hints: the number of days becomes days_before_due with a default of 3, and the urgency flag becomes a named priority option. Every call must now name its arguments, for example send_reminder(user, days_before_due=7, priority="high"), and a type checker flags the old mistake before deployment. The outcome is calls that explain themselves and a class of bugs that can no longer reach production.