Lesson 5 of 54

The Art of Naming

Names That Pack Information

A colleague once asked me to review a function called process. It took a parameter called data and returned a value called result.

I stared at it for 5 minutes before asking: "What does this actually do?"

"It converts user timestamps to the local timezone," he said.

That function should have been called convertTimestampsToLocalTimezone. The parameter should have been userEvents. The return value should have been localizedEvents.

Naming is not decoration. It's documentation that can't go stale.

The Specificity Principle

Generic names are placeholders. Specific names are information.

GenericSpecific
datauserProfile, orderHistory, sensorReadings
temppreviousBalance, cachedResponse, retryDelay
resultvalidatedEmail, calculatedTotal, filteredProducts
handlerpaymentWebhookHandler, errorResponseHandler
processnormalizeAddress, calculateShipping, parseLogEntry

Every time you type a generic name, you're making the next reader do extra work.

The Word Association Test

Here's a technique from The Art of Readable Code: imagine someone reading just the name, with no context. What might they assume?

Take fetchData:

  • Data about what?
  • From where? Database? API? File?
  • In what format?

Now take fetchUserProfileFromCache:

  • It's about user profiles
  • It comes from a cache
  • It implies there's probably also a fetchUserProfileFromDatabase

The second name prevents wrong assumptions.

Words to Avoid

Some words are almost always filler:

data — Everything is data. What kind of data?

info — Same problem. userInfo should be userProfile or userCredentials or userPreferences.

temp — If it's temporary, what is it for? previousValue, swapBuffer, intermediateResult.

thing, stuff, item — These are admissions that you don't know what you're naming.

Manager, Handler, Processor — These often indicate a class doing too much. We'll cover this more in the classes lesson.

Length vs. Clarity

"But long names are hard to type!"

Two responses:

  1. Your IDE autocompletes after 3 characters
  2. You type the name once; others read it hundreds of times

A name should be as long as necessary to be clear, and no longer.

ScopeAppropriate Length
Loop counter (2-line scope)i, j, k are fine
Local variable (10-line scope)Short but descriptive: total, user, items
Function parameterDescriptive: userId, startDate, options
Class fieldFull context: maximumRetryAttempts, defaultTimeoutSeconds
Global/constantVery explicit: MAX_CONNECTION_POOL_SIZE, DEFAULT_CACHE_TTL_SECONDS

The longer the scope, the more descriptive the name needs to be.

Code Transformation Example

This function exists in many codebases:

Javascript
function process(d) {
  const t = d * 24;
  return t;
}

What does it do? You'd have to trace every call site to find out.

Now:

Javascript
function daysToHours(days) {
  const hoursPerDay = 24;
  return days * hoursPerDay;
}

Same logic. But the name tells you:

  • Input: days
  • Output: hours
  • Operation: conversion

You can understand this function without reading its body. That's the goal.

The Search Test

Can you search for your variable in the codebase and find it?

If your variable is named e, d, or x, searching for it will return thousands of false positives.

If your variable is named errorCount, deliveryDate, or xCoordinate, you can find every usage instantly.

Searchability matters for refactoring, debugging, and understanding.

Practical Exercise

Go to your codebase right now. Search for variables named:

  • data
  • temp
  • result
  • item
  • obj

Pick 10 of them. For each one, rename it to describe what it actually holds.

This exercise will improve your codebase more than many hours of "refactoring."


Key insight: Names are compressed documentation. Every generic name (data, temp, result) forces readers to expand it manually by reading surrounding code. Specific names (userProfile, previousBalance, validatedEmail) carry their meaning with them.