Lesson 7 of 54

The Art of Naming

Units, Context, and Encoding in Names

In 1999, NASA's Mars Climate Orbiter disintegrated in the Martian atmosphere. The cause: one team calculated thrust in pound-seconds, another expected newton-seconds. The variable was just called thrust.

If it had been called thrustPoundSeconds or thrustNewtonSeconds, someone would have noticed.

Units in names save missions. They also save production incidents.

Include Units in Names

When a variable represents a quantity, include the unit:

VagueClear
timeouttimeoutMs, timeoutSeconds
delaydelayMs, retryDelaySeconds
sizesizeBytes, sizeMB, sizeKB
pricepriceInCents, priceDollars
distancedistanceMeters, distanceMiles, distanceKm
weightweightGrams, weightKg, weightPounds
durationdurationMs, durationMinutes, durationDays

This prevents unit conversion bugs—one of the most common and hard-to-catch bug categories.

Real Example

Javascript
// Bug waiting to happen
function setSessionTimeout(timeout) {
  this.timeoutId = setTimeout(expire, timeout);
}

// Called with seconds, but setTimeout expects milliseconds
setSessionTimeout(30);  // Expires in 30ms, not 30s!

Fixed with unit-explicit naming:

Javascript
function setSessionTimeoutSeconds(timeoutSeconds) {
  const timeoutMs = timeoutSeconds * 1000;
  this.timeoutId = setTimeout(expire, timeoutMs);
}

setSessionTimeoutSeconds(30);  // Obviously 30 seconds

Now the name documents the expected unit, and the conversion is explicit.

State and Status Prefixes

Prefixes can encode important context about a value's state:

raw — Unprocessed, potentially unsafe

Javascript
const rawUserInput = request.body.comment;
const sanitizedComment = sanitize(rawUserInput);

Anyone reading rawUserInput knows: this hasn't been validated or sanitized. Don't put it in the database or render it directly.

safe — Validated/sanitized

Javascript
const safeHtml = sanitizeHtml(rawHtml);
document.innerHTML = safeHtml;  // OK to use

cached — From cache, might be stale

Javascript
const cachedUser = userCache.get(userId);
const freshUser = await fetchUser(userId);

validated — Passed validation

Javascript
const validatedEmail = validateAndNormalizeEmail(rawEmail);

partial — Incomplete data

Javascript
const partialOrder = { items: [...], /* missing shipping address */ };

Encoding Safety Information

Some of the worst bugs come from mixing safe and unsafe data. Names can prevent this.

SQL Injection Prevention

Javascript
// Dangerous: Is this escaped?
const query = `SELECT * FROM users WHERE name = '${name}'`;

// Clear: The name tells you
const escapedName = escapeSQL(userProvidedName);
const query = `SELECT * FROM users WHERE name = '${escapedName}'`;

XSS Prevention

Javascript
// Dangerous: Is this sanitized?
element.innerHTML = content;

// Clear: The name documents safety
const sanitizedContent = DOMPurify.sanitize(userContent);
element.innerHTML = sanitizedContent;

Encoding Conventions

Some teams use naming conventions for safety:

  • unsafeHtml — raw, potentially malicious
  • safeHtml — sanitized, safe to render
  • trustedHtml — from trusted source, no sanitization needed

The convention doesn't matter. Consistency does.

Scope-Appropriate Length

Name length should match scope size.

Tiny Scope: Short Names OK

Javascript
// 2-line loop: i is fine
for (let i = 0; i < items.length; i++) {
  process(items[i]);
}

// Single-use lambda: short parameter OK
users.filter(u => u.isActive);

Medium Scope: Descriptive

Javascript
function calculateTax(order) {
  const subtotal = order.items.reduce((sum, item) => sum + item.price, 0);
  const taxRate = getTaxRate(order.shippingAddress);
  const taxAmount = subtotal * taxRate;
  return taxAmount;
}

Large Scope: Very Explicit

Javascript
class OrderProcessor {
  private readonly maximumRetryAttempts = 3;
  private readonly retryDelayMilliseconds = 1000;
  private readonly connectionTimeoutSeconds = 30;
}

Module/Global Scope: Full Context

Javascript
const DEFAULT_SESSION_TIMEOUT_MINUTES = 30;
const MAX_FILE_UPLOAD_SIZE_BYTES = 10 * 1024 * 1024;
const API_RATE_LIMIT_REQUESTS_PER_MINUTE = 100;

Encoding Important Constraints

Names can document constraints that would otherwise require comments:

Javascript
// Instead of a comment
// Note: this is 1-indexed
const pageNumber = 1;

// Encode it in the name
const oneIndexedPageNumber = 1;

// Or use domain language
const humanPageNumber = 1;  // As displayed to user (1-indexed)
const arrayIndex = humanPageNumber - 1;  // For array access (0-indexed)

Context from Container

You don't need to repeat context that's already clear from the container:

Javascript
// Redundant
class User {
  userName: string;
  userEmail: string;
  userCreatedAt: Date;
}

// Better: context is provided by class
class User {
  name: string;
  email: string;
  createdAt: Date;
}

But when the variable leaves its container, add context back:

Javascript
// Inside User class: fine
this.email

// Outside User class: need context
const userEmail = user.email;
const orderEmail = order.contactEmail;

Key insight: Names can encode critical safety information. Units prevent conversion bugs. Prefixes like raw, safe, and cached prevent security bugs and stale data bugs. Make the name carry the warning.