Why you shouldn't default to positional parameters

software-engineering
Back
// 😤 positional parameter madness
activateEntity(1,true,true,false,new Date())

Ok so I probably shouldn't care enough, it's such a small, tiny thing, it almost doesn't even deserve a blog post but dammit! I keep seeing positional parameters used everywhere and I feel I have to make a full position on why there is no good reason to use positional parameters beyond maybe 2.

Readability

Positional parameters are inherently less readable. They can be acceptable for one or two values, but anything beyond that starts becoming a cognitive burden.

Consider this example:

// 😭 Positional parameters
updateUser(id, true, 1200, false);

// 🥳 Named parameters
updateUser({
  id,
  isActive: true,
  points: 1200,
});

The second version is not only more readable but also self-documenting. Anyone reading the code can immediately understand what each parameter represents without needing to look up the function definition.

Adding new parameters

When using positional parameters, adding new ones is always a challenge. You could add it in whatever index you think is the most semantically appropriate place. This will likely break your API, which means you now need to refactor all usages. So clearly not an option in most cases.

So you add it at the end instead. And so the position ends up meaning nothing other than the order in which params where added.

With named parameters, on the other hand, it's simple. Adding a new parameter doesn’t require careful consideration of order, nor does it risk turning existing calls into a guessing game of what the parameters mean.

Generally speaking, this is what I call "addition-safe". You should generally design your software systems so that adding functionality doesn't break existing usages.

Positional parameter momentum

It always starts simple. Your function initially takes two parameters, so you go with positional because it feels more natural. But time passes. The next dev needs to add two more parameters. Should they refactor the code? or just keep piling the parameters positionally.

Of course they are not going to refactor the code. They need to get work done.

So they add more positional parameters to the list, and soon enough you end up with positional parameter madness.

This is what I call positional parameter momentum. When a function starts out with positional parameters it has a tendency to stay that way.

The converse is also true. When a function starts out using nominal parameters, it also stays that way.

Performance is not a good argument for positional parameters

You might hear the argument that creating an object for named parameters is less performant. Unless you've meticulously benchmarked your code and found a significant bottleneck, this argument is moot. The slight increase in memory usage for the object allocation is unlikely to impact performance in any meaningful way for the majority of use cases.

The readability and maintainability gains you achieve by using named parameters far outweigh any negligible performance difference. In most real-world applications, code clarity and developer productivity are far more critical metrics than micro-optimizations.

Make the change

Next time you’re writing a function, consider ditching positional parameters. Opt for named parameters instead. Your future self—and any colleagues working with your code—will thank you.

If you found this article useful, consider following me on twitter. I write about once a month about software engineering practices and programming in general.

I'm also developing SynthQL. A type-safe HTTP client for PostgreSQL and I would love to get your feedback.


Other posts you may like...

© Fernando Hurtado Cardenas.RSS