# Naming and Functions — Clean Code Chapters 2 and 3 Source: Robert C. Martin, *Clean Code*. Sample chapters online at the Pearson PDF; chapter summaries at Vivek Khatri's Ch. 2 notes and Herberto Graça's Ch. 3 summary. ## Contents - Meaningful names - N1. Intention-revealing - N2. No disinformation, no encodings - N3. Meaningful distinctions - N4. Searchable, pronounceable - N5. Class names are nouns, method names are verbs - N6. Banned generic names - Functions - F1. Small. Then smaller. - F2. Do one thing - F3. One level of abstraction per function - F4. Step-down rule - F5. Few arguments - F6. No flag arguments - F7. No output arguments / Command-Query Separation - F8. No side effects in queries - F9. Prefer exceptions to return codes - F10. Duplication is the root evil - Self-check for naming and functions ## Meaningful names ### N1. Intention-revealing A name should tell you *why it exists, what it does, and how it's used*. If you need a comment to explain a name, the name is wrong. **Bad:** ```text d // elapsed time in days ts = [] fn(xs) ``` **Good:** ```text elapsedDays timestamps filterOverdueInvoices(invoices) ``` ### N2. No disinformation, no encodings No Hungarian notation (`strName`, `iCount`). No interface-prefix `I` (`IUserService`). No member prefix `m_`. No "List" suffix unless the type is actually a list (`accountList` for a `set` is disinformation). **Bad:** `strFirstName`, `IUserRepo`, `m_count`, `userArray` (when it is not an array). **Good:** `first_name`, `UserRepo`, `count`, `users_by_id`. ### N3. Meaningful distinctions Do not differentiate names by adding noise words. `ProductInfo`, `ProductData`, `Product` — what's the difference? Same with `getActiveAccount` vs. `getActiveAccountInfo`. If the distinction is real, name the distinction. ### N4. Searchable, pronounceable Single-letter names are acceptable inside short loop scope (`for i in range(...)`). Anywhere else they hurt grep. `MAX_RETRIES` is searchable; `7` is not. If you can't read the name aloud in a code review, it's a bad name. `genymdhms` is a real-world example from the book — `generation_timestamp` is the fix. ### N5. Class names are nouns, method names are verbs `User`, `Invoice`, `Account` — classes are things. `saveInvoice`, `computeTotal`, `notifyUser` — methods are actions. A class named `ProcessInvoice` and a method named `Invoice` are both wrong. ### N6. Banned generic names Without a qualifier, these names always violate intention-revealing: - `data`, `data2`, `data_final` - `result`, `result_final` - `item`, `value`, `temp`, `obj`, `info` - `helper`, `manager`, `utils`, `common` - `handle_*`, `process_*`, `do_*` (when `*` is also generic) Qualified versions are fine: `raw_csv_bytes`, `parsed_invoice`, `dedup_by_email`. --- ## Functions ### F1. Small. Then smaller. Target ≤20 lines. Uncle Bob's harder pass says 2–4 lines is the goal. If a function does not fit on a screen, it does too much. Extract. ### F2. Do one thing A function does one thing when you cannot extract another function from it with a name that is not a restatement of its body. If `compute_invoice` contains a 10-line block that you could meaningfully call `apply_discount`, the original was doing more than one thing. ### F3. One level of abstraction per function Mixing levels is the most common subtle defect. Do not put an HTTP call, a SQL query, a regex parse, and a business rule in the same function — those are four levels. **Bad:** ```text renderUserReport(userId): connection = openDatabaseConnection() row = queryUserRow(connection, userId) displayName = row.firstName + " " + row.lastName markup = "