The 3-Argument Rule: How to Stop "Argument Bankruptcy"

Search for a command to run...

No comments yet. Be the first to comment.
TL;DR: JavaScript has notorious quirks because it was designed in just ten days as a prototype to help Netscape survive the early browser wars. Because the internet relies on absolute backwards compat

Quick Answer: SQL injection attacks exploit vulnerabilities in how web applications construct database queries. By sending malicious SQL code through user input fields (like search bars), attackers ca

Stop wasting your context window explaining industry standards to LLMs. Large Language Models already have best practices baked into their training data; you just need to activate those specific regio

The Netflix Keeper Test asks managers: "If this engineer resigned today, would you fight to keep them?" While it ensures high talent density, I believe it often destroys psychological safety. For most

Quick Answer: No, AI agents won't replace software engineers, but they are flipping the table on how we work. While agents excel at writing generic, path-of-least-resistance code, they lack opinion. H

You are reading a file, trying to debug a critical issue. You stumble upon this line:
createUser("John", "Doe", "j@d.com", true, false, 5);
Your brain freezes.
What is true? What is false? What does the number 5 represent? Is that a retry count? A timeout? A user ID?
To understand this single line of code, you have to navigate to the function definition, memorize the order of six different parameters, and then mentally map them back to the function call.
You have just paid a heavy tax.
In "The Professional Junior," I talk about the concept of Cognitive Budget. As developers, we can only hold so much context in our heads at once. Every time we force a caller to memorize an argument order, we deplete that budget.
This is called Argument Bankruptcy. Here is how to fix it.
Think of arguments as the taxes we pay to use a function.
getUser(id) or login(username, password).When a function requires three or more arguments, we introduce two major risks:
true or false without context makes the calling code unreadable.(email, name) or (name, email)? In loosely typed languages, getting this wrong leads to silent data corruption. In typed languages, it leads to frustration.We’ve all been there. You have a function that takes three arguments. A new requirement comes in: we need to track the user's last login date.
The easy path (The Junior Trap) is to just tack it onto the end.
function save(name, email, isAdmin, lastLogin) { ... }
Six months later, another requirement comes in. Now we need a retry count. Tack it on the end.
Suddenly, you are playing "Guess the Argument" every time you call the function.
The solution is to stop passing loose data. If logic requires 3+ things, those things belong together. We wrap them in a single object (or Interface).
Here, the caller is forced to memorize the specific order of five different variables. If they swap the booleans, an admin might get downgraded to a standard user silently.
// ❌ The Function Definition
function saveUser(
firstName,
lastName,
email,
isAdmin,
sendWelcomeEmail
) {
// ... implementation
}
// ❌ The Usage (The Horror)
// What does 'true' mean? What does 'false' mean?
// If I swap them, I break the system.
saveUser("John", "Doe", "j@d.com", true, false);
By using a single object argument (often called "named parameters" or the "RObject pattern"), we eliminate the tax.
isAdmin is because the key says so.// ✅ The Function Definition
// We expect ONE object.
function saveUser(userContext) {
// We can destructure immediately for clarity
const { firstName, email, isAdmin } = userContext;
// ... implementation
}
// ✅ The Usage (Clear & Robust)
saveUser({
firstName: "John",
lastName: "Doe",
email: "j@d.com",
isAdmin: true,
sendWelcomeEmail: false
});
The greatest benefit of the After approach is how it handles change.
If you need to add a middleName parameter to the Before example, you have to find every instance of saveUser in your application and update the arguments, or carefully place it at the very end and hope no one messed up the order.
In the After example, you add middleName to the function logic. Old calls that don't pass middleName simply treat it as undefined (or you provide a default), and the code keeps running.
Stop making your teammates memorize your implementation details. Pay the tax for them.
Stop writing code just to please the compiler.
This article was an excerpt from my handbook, "The Professional Junior: Writing Code that Matters."
It’s not a 400-page textbook. It’s a tactical field guide to unwritten engineering rules.