I have lost count of the times I have read a call with five positional arguments and had to count commas backwards to work out which one is the timeout and which is the retry count. The fix has been in the catalogue since 1999: introduce a parameter object. Bundle the fields that keep travelling together and give the bundle a name and a type. The call sites stop reading like SQL with the column names removed.
The trigger I use is the third caller. Two call sites passing the same group can be coincidence. A third one tells you the concept has been in the domain all along without anyone naming it. A third caller passing the same group is the point at which the group wants a name. Waiting for a lint warning misses this, because the warning fires on width and the problem is that the group has no name.
The cap is editorial and we set it the same way, max-params at 3. But the rule catches the symptom rather than the cause. A constructor taking four loose strings passes nothing and fails everything, while a four-argument call where three of them are genuinely independent is fine. The rule makes you look.
A parameter object does not automatically improve things. Once a function takes a parameter object, every caller has to build one, and if that object is a bag with no methods you have moved the comma-counting to the construction site. The object should be the place the validation lives, so an invalid one cannot be built. If it is only a struct, you have added a hop.
Naming the object usually turns up a domain word that was not in the codebase before. That part still surprises me. The extraction is mechanical, but the name is a decision. You were avoiding that decision every time you typed that fifth argument.
I run the same reasoning on agents now. An agent handed a five-argument signature will keep adding positional arguments, because the shape it sees is the shape it copies. It cannot count commas backwards either.
The longer version is at https://prickles.org/tenet/parameter-object/S3
“Anybody can make software now”
You were avoiding that decision every time you typed that fifth argument.
Mate, I don’t think copying and pasting an overly verbose AI code review because your code has tech debt is all that helpful to other people.
A third one tells you the concept has been in the domain all along without anyone naming it.
Especially when the recipe is full of bullshit filler liked this. That’s a completely arbitrary rule and treats the obvious as profound. It isn’t.
The cap is editorial and we set it the same way, max-params at 3. But the rule catches the symptom rather than the cause. A constructor taking four loose strings passes nothing and fails everything, while a four-argument call where three of them are genuinely independent is fine. The rule makes you look.
This whole paragraph is completely useless. It says fucking nothing and just makes the whole thing harder to read.
object is a bag with no methods you have moved the comma-counting to the construction site.
Which is still an improvement, especially if the parameter object is immutable. You can build it one at the proper time and place and you’re done. Or create a builder.
The object should be the place the validation lives, so an invalid one cannot be built. If it is only a struct, you have added a hop.
Why does AI talk to you like everyone is a green first year dev that needs to be told obvious shit every time?
That part still surprises me. The extraction is mechanical, but the name is a decision. You were avoiding that decision every time you typed that fifth argument.
Jesus fucking christ I hate Claude. I wish it wasn’t the best coding AI.
The longer version is at
Are you fucking kidding me with this? This is already 4x as long as our needs to be.
I’m not normally this direct and impolite, but I’m taking it out on you because I can’t yell at my coworkers who do the same shit and worse.
So much slop text
Or use an ide that shows the argument name inline for you. Its 2026, your editor can help you.
In my experience, naming the elements in an object requires exactly the same documentation as naming the elements in a function call and it makes things worse if you forget to assign a value to one of them, since the object constructor will likely assign an unknown default value.
If you’re using a language that cares about data types that’s not possible.
Which bit isn’t possible?
As far as data types goes, you can apply the same logic to function parameters.
if you forget to assign a value to one of them, since the object constructor will likely assign an unknown default value.
This bit - in a language that cares about types that should either not be possible or difficult to do by accident.
That depends entirely on how the object is constructed. Plenty of implementations use object.new() and you’re expected to fill in the blanks.
Besides, even if you have a constructor that takes parameters, it’s essentially the same as calling a function. Get it wrong and stuff breaks.
That depends entirely on how the object is constructed. Plenty of implementations use object.new() and you’re expected to fill in the blanks.
That’s because some languages simply do not give a shit about data types. They’re just like “your opinion man” and can even vary at runtime which creates lots of exciting errors as you’re pointing out. Enjoy writing lots of type-checks.
In a language that does care about types you can control that and don’t worry about it.
Besides, even if you have a constructor that takes parameters, it’s essentially the same as calling a function. Get it wrong and stuff breaks.
data class UserRequest { val id: Int, val name: String }No guesswork. All values must be provided and none can be ‘null’. Well designed languages help you avoid such problems. Poorly designed languages facilitate it.
How is your code sample for an object any different from a function definition?
In both cases you need to read the documentation, consult the source, or have an IDE that does.
I thought it was clear that I was responding to “if you forget to assign a value to one of them, since the object constructor will likely assign an unknown default value.”
I’m not defending the article.


