How to Read Code Formatting
Programmers spend most of their time reading other people’s code. When adding features or fixing bugs, you first need to understand the intent of the existing code. In this context, formatting—indentation, line length, whitespace—isn’t just surface-level presentation; it’s a crucial signal that communicates code structure and complexity.

Indentation: Visualizing Scope
Indentation makes code scope relationships explicit.
def calculate_total(items):
total = 0
for item in items:
if item.price > 0:
total += item.price
return total
In this code, total = 0 is valid in the function’s scope, the for loop is nested within it, and the if statement exists only within the loop. Indentation makes these relationships clear.
What happens when indentation ignores convention? Python treats it as a syntax error, but languages that use braces like Java or C are different.
// Indentation mistakes in brace languages
if (condition) {
int x = 0; // Actually outside the if block
doSomething(); // This line is also outside the if block
}
The compiler follows the braces, but the actual logic conflicts with what the indentation suggests. This isn’t just a readability issue—it’s a mismatch between intent and behavior.
Deep nesting signals multiple conditions or loops. One way to improve it is with early returns (guard clauses).
// Before: deep nesting
function processUser(user) {
if (user) {
if (user.isActive) {
if (user.balance > 0) {
sendNotification(user.email);
updateBalance(user.id);
}
}
}
}
// After: guard clauses
function processUser(user) {
if (!user) return;
if (!user.isActive) return;
if (user.balance <= 0) return;
sendNotification(user.email);
updateBalance(user.id);
}
Early returns eliminate unnecessary nesting and expose the core logic upfront.
Line Length and Layout: Signals of Complexity
Placing code step-by-step on shorter lines makes the flow of work clear.
List<String> names = users.stream()
.filter(user -> user.isActive())
.map(User::getName)
.sorted()
.collect(Collectors.toList());
Each method appears on its own line, making the intent obvious: a sequential transformation pipeline. What if you cram it all into one line?
List<String> names = users.stream().filter(user -> user.isActive()).map(User::getName).sorted().collect(Collectors.toList());
Same functionality, but much harder to read and harder to find individual steps when editing.
Function parameters follow the same principle. Many parameters don’t always mean the function has too many responsibilities—configuration objects or rendering functions can legitimately have many arguments while maintaining a single concern. But arranging parameters clearly reveals complexity at a glance.
# One line: complexity is hidden
def create_report(name, date_start, date_end, include_summary, include_charts, format_type): pass
# Clearly laid out: complexity is visible
def create_report(
name,
date_start,
date_end,
include_summary,
include_charts,
format_type
):
pass
Whitespace and Blank Lines: Logical Boundaries
Blank lines separate logically related groups of code.
function authenticate(username, password) {
const user = database.findUser(username);
if (!user) return null;
const hashedPassword = hash(password);
if (user.passwordHash !== hashedPassword) return null;
const token = generateToken(user.id);
return token;
}
Blank lines divide three logical steps: “user lookup” → “password verification” → “token generation”. Without them, it’s unclear whether each step is independent or related.
Spacing around operators also clarifies intent.
# Clear
result = (a + b) * c - d
# Unclear
result = (a+b)*c-d
Automatic Formatters and Style Guides
In modern development, formatting is mostly handled automatically. Tools like Black for Python, Prettier for JavaScript, and gofmt for Go enforce consistent style without manual effort. Instead, teams adopt a style guide like PEP 8 or the Google Style Guide and configure their formatter accordingly.
Adopting a formatter brings two major benefits. First, formatting debates disappear. Second, diffs stay clean, making code reviews more efficient—no unnecessary whitespace changes clutter the view, just actual logic changes.
Conclusion
Formatting is the quickest signal of the author’s intent. The depth of indentation, the length of lines, and the placement of whitespace all reveal how complex code is and what problem it’s solving. By maintaining consistency with an automatic formatter and following a style guide, code becomes easier to read, and collaboration and version control become smoother. Next time you read code, start by observing formatting patterns. Often, that alone will reveal substantial information about complexity and intent.
'코드를 읽는 방법' 카테고리의 다른 글
| [Git History] Decode the Why Behind Every Line of Code (0) | 2026.05.29 |
|---|---|
| [Git] "왜 이렇게 만들었을까"의 답이 여기 있다 (0) | 2026.05.29 |
| [코드 읽기] 포매팅이 말해주는 의도 (0) | 2026.05.28 |
| [Code Patterns] How Names Reveal What Code Really Does (0) | 2026.05.27 |
| [주석 해석] 코드 한 줄의 진짜 의도를 읽는 법 (0) | 2026.05.27 |