DEV Community

Cover image for Beyond `i` and `tmp`: Writing Code for Humans, Inspired by Grace Hopper
Aaron Rose
Aaron Rose

Posted on

Beyond `i` and `tmp`: Writing Code for Humans, Inspired by Grace Hopper

If you've spent any time in programming communities, you've seen them: the unwritten rules. The "universal" conventions like using i, j, k for loop counters or tmp and val for temporary variables. They’re presented as a shared language, a way to make code feel familiar.

But what happens when "the way it's always been done" starts to obscure what the code actually does? What if our quest for convention sacrifices the very readability we seek?

This isn't a new question. Admiral Grace Hopper, a pioneer who helped make programming languages accessible, famously focused on one core principle: We write code for humans to understand, and only incidentally for machines to execute.

Let's explore some common conventions through her lens and discover how we can write Python that is not just conventional, but profoundly clear.

1. The Looping Variable: From Indices to Meaning

The Convention: Use i, j, k for loop counters.

# Conventional Approach
for i in range(len(users)):
    print(users[i].name)
Enter fullscreen mode Exit fullscreen mode

This is familiar, but it requires a mental translation. What is i? It's an index. What we really care about is the user at that index.

The Hopper Principle: Name variables for their role in the logic, not their data structure.

# Clarity-First Approach
for user in users:
    print(user.name)

# Or, if you genuinely need the index:
for index, user in enumerate(users):
    print(f"User {index}: {user.name}")
Enter fullscreen mode Exit fullscreen mode

By naming the variable user, we eliminate the cognitive overhead. The code states its intent directly. The loop is no longer about counting; it's about processing users.

2. The "Temporary" Variable: A Failure of Imagination?

The Convention: Use tmp, temp, or val for short-lived values.

# Conventional Approach
tmp = calculate_total(items)
final_price = tmp * (1 - discount)
Enter fullscreen mode Exit fullscreen mode

Names like tmp are a black box. They tell you what the variable is (temporary) but nothing about why it exists or what it represents.

The Hopper Principle: Every variable, no matter how short-lived, has a purpose. Its name should reveal it.

# Clarity-First Approach
subtotal = calculate_total(items)
final_price = subtotal * (1 - discount)
Enter fullscreen mode Exit fullscreen mode

The name subtotal is just as concise as tmp, but it carries meaning. It tells the reader that this is the total before the discount is applied. The logic of the calculation becomes self-documenting.

3. The Hungarian Notation Hangover: Encoding Types in Names

The Convention: Prefix variable names with their type (arr_users, dict_config, str_name).

# Conventional Approach
list_employees = get_employees()
dict_employee_info = list_employees[0]
Enter fullscreen mode Exit fullscreen mode

This style, often called "Hungarian notation," was more relevant in statically-typed languages without modern IDEs. In Python, it adds noise. Your editor can already tell you the type; your variable name should tell you the purpose.

The Hopper Principle: Trust your tools and your teammates. Name for concept, not for type.

# Clarity-First Approach
employees = get_employees()  # We know it's a list from the context
primary_employee = employees[0]
employee_info = primary_employee.data # We know it's a dict, or we can look it up
Enter fullscreen mode Exit fullscreen mode

The code is cleaner and focuses on the business logic—managing employees—not the implementation details of the data structures.

4. The Boolean Trap: Asking "What?"

The Convention: Prefix booleans with is, has, or should.

# Conventional Approach
if product.is_available and user.has_permission:
    ...
Enter fullscreen mode Exit fullscreen mode

This is actually a good convention! But we can take it a step further. The real trap is writing a condition that requires a comment to explain why.

The Hopper Principle: Write code that reads like a sentence. Extract complex logic into descriptive variables.

# Clarity-First Approach
product_is_available = product.in_stock and not product.discontinued
user_can_purchase = user.has_permission and user.is_verified

if product_is_available and user_can_purchase:
    ...
Enter fullscreen mode Exit fullscreen mode

Now, the if statement is a perfectly readable sentence. More importantly, the reasons behind the conditions are now explicit, preventing bugs and making the code far easier to reason about.

The Unwritten Rule That Trumps All Others

Grace Hopper's legacy reminds us that the most dangerous phrase in any language is, "We've always done it this way." Conventions are useful starting points, but they should be servants to clarity, not its master.

The true, unwritten rule of programming is this: Write code for the human who will read it next, even if that person is you in six months.

So, the next time you reach for i or tmp, pause. Ask yourself:

  • "What does this variable actually represent in the real-world problem I'm solving?"
  • "Can I make this conditional read like a simple sentence?"
  • "Will the next developer understand the why just as easily as the what?"

Don't just write code that works. Write code that explains itself. That’s the spirit of true clean code, and it’s a standard worthy of Admiral Hopper herself.


Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.

Top comments (0)