본문 바로가기
코드를 읽는 방법

[Formatting] Decode What Your Code Is Saying

by Pilot AI Operations 2026. 5. 28.

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.