Skip to main content

Naming, Readability, and Intent

Master naming conventions that clarify code intent and improve readability across all programming contexts.

TL;DR

Code is read far more often than it's written. Choose names that reveal intent: use pronounceable, searchable names that indicate purpose and type. Avoid single letters outside loops, magic numbers, and abbreviations that require external knowledge. Use consistent naming patterns across your codebase so readers can predict what a name means without hunting for definitions. Names are your primary communication tool—use them to reduce the need for comments.

Learning Objectives

  • Understand why naming is a critical communication mechanism in code
  • Apply rules for choosing clear, intent-revealing names for variables, functions, and classes
  • Distinguish between good and harmful abbreviations
  • Implement consistent naming conventions across projects
  • Recognize how readability debt compounds over time

Motivating Scenario

You return to a module you wrote six months ago. Scanning the code, you encounter: const x = data.map(d => d.f); const r = x.filter(v => v > t);. Without external documentation or memory, you cannot determine what this code does. Days later, you find comments explaining f is a field value and t is a threshold, but the code itself provides no clue. This is a readability failure.

Now compare: const fieldValues = data.map(item => item.fieldValue); const aboveThreshold = fieldValues.filter(value => value > threshold);. The code now explains itself. Future maintainers—and your future self—understand instantly what's happening.

Core Concepts

Intent Over Mechanism

Names should reveal why something exists, not just what it does. A name like getUserData() is worse than fetchActiveUserProfile() because the first only describes mechanics while the second explains intent and possible side effects.

Context and Type Information

Good names provide enough context that readers don't need to jump to definitions. activeUsers is clearer than users when the distinction matters. Prefixes like is, has, or should for booleans immediately signal type: isActive, hasPermission, shouldRetry.

Searchability and Consistency

Single-letter variables and abbreviations make code unsearchable. Searching for "n" in a codebase returns thousands of false positives. Consistent naming patterns mean developers can predict variable names without hunting for them.

Practical Example

# ❌ POOR - No context, unclear intent
def proc(d):
r = []
for x in d:
if x['s'] > 50:
r.append(x['nm'])
return r

# ✅ EXCELLENT - Clear intent and context
def extract_high_performers(employees):
"""Extract names of employees with sales above threshold."""
high_performers = []
performance_threshold = 50

for employee in employees:
if employee['sales'] > performance_threshold:
high_performers.append(employee['name'])

return high_performers

# Even better with list comprehension and clear naming
def get_high_performer_names(employees, threshold=50):
return [emp['name'] for emp in employees if emp['sales'] > threshold]

Naming Patterns by Context

Variables

Use full, pronounceable names. Exceptions:

  • Loop counters: i, j, k (universally understood)
  • Well-known abbreviations: url, json, http
  • Mathematical formulas: x, y, z (only in mathematical contexts)
// ❌ Poor
const usd = 100;
const ccn = "4532";
const pmt = calcPmt(amt, rt);

// ✅ Good
const usdAmount = 100;
const creditCardNumber = "4532";
const monthlyPayment = calculatePayment(loanAmount, interestRate);

Booleans

Prefix with is, has, should, can, or will to make type obvious:

// ❌ Unclear type
const active = user.status === 'active';
const admin = user.roles.includes('admin');

// ✅ Type is immediately clear
const isActive = user.status === 'active';
const hasAdminRole = user.roles.includes('admin');
const shouldNotify = isActive && !user.muteNotifications;
const canDelete = hasAdminRole || isOwner;

Functions

Use verb-noun patterns. getUser(), calculateTotal(), validateEmail(), processPayment(). Avoid generic verbs like handle, process, manage unless truly domain-agnostic:

// ❌ Vague verbs
function handle(data) { /* ? */ }
function process(item) { /* ? */ }

// ✅ Specific intent
function validateUserEmail(email) { /* ? */ }
function enrichEmployeeProfile(employee) { /* ? */ }
function persistChangeLog(changes) { /* ? */ }

Constants

Use UPPER_SNAKE_CASE to indicate they won't change during execution:

// ❌ Unclear mutability
const timeout = 5000;
const apiVersion = 'v2';

// ✅ Obviously constant
const REQUEST_TIMEOUT_MS = 5000;
const DEFAULT_API_VERSION = 'v2';
const MAX_RETRY_ATTEMPTS = 3;

When Names Become Technical Debt

The Abbreviation Trap

Abbreviations save typing but damage readability. "temp", "msg", "acc", "dup"—these require mental translation overhead. That overhead compounds: when you return to code later, you must re-learn what every abbreviation means.

The Single-Letter Variable Epidemic

Outside mathematical contexts and loop counters, single letters are unforgivable:

// ❌ Impossible to search
const u = getUser();
const p = u.profile;
const a = p.address;

// ✅ Searchable and clear
const user = getUser();
const userProfile = user.profile;
const userAddress = userProfile.address;

Magic Strings and Numbers

Extract them to named constants so readers understand significance:

// ❌ What do these numbers mean?
if (user.age > 18 && user.daysActive > 365) {
enablePremium(user);
}

// ✅ Intent is clear
const ADULT_AGE = 18;
const MINIMUM_ACTIVE_DAYS = 365;

if (user.age > ADULT_AGE && user.daysActive > MINIMUM_ACTIVE_DAYS) {
enablePremium(user);
}

Design Review Checklist

When reviewing naming in code, ask:

  • Can you understand what a variable contains without inspecting its assignment?
  • Can you search for a name and find all relevant occurrences?
  • Do boolean variable names start with is, has, should, or can?
  • Are single letters used only for loop counters and mathematical contexts?
  • Are magic numbers and strings extracted to named constants?
  • Do function names clearly indicate what they do?
  • Would a future reader understand this code without external documentation?
  • Are abbreviations limited to well-known terms (URL, JSON, HTTP)?

Self-Check

  1. Find a variable in your codebase named with a single letter or cryptic abbreviation. How would you rename it to be more clear?

  2. Examine a function that takes boolean parameters. How could you refactor it to use more descriptive parameter or variable names?

  3. What abbreviations appear most frequently in your code? Are they truly necessary, or would full names improve readability?

One Takeaway

Names are your primary tool for communicating intent to other developers (and your future self). Spend the extra seconds typing a clear, full name. The cost of typing is negligible compared to the cost of developers struggling to understand cryptic code. A well-named codebase is a readable codebase, and readable code is maintainable code.

Next Steps

References

  1. Martin, R. C. (2008). Clean Code: A Handbook of Agile Software Craftsmanship. Prentice Hall.
  2. Hunt, A., & Thomas, D. (1999). The Pragmatic Programmer: Your Journey to Mastery in Software Development. Addison-Wesley.
  3. McConnell, S. (2004). Code Complete: A Practical Handbook of Software Construction. Microsoft Press.
  4. Fowler, M. (2018). Refactoring: Improving the Design of Existing Code (2nd ed.). Addison-Wesley.