Sitemap

Sustainable Space

A pattern for stable code formatting

6 min readJun 12, 2026
Press enter or click to view image in full size
OV-104 at Kennedy Space Center

You are coding in a block-structured language in a codebase where developers need to be able to read and edit the code. Spacing is normally used in source code to improve readability through visual separation and logical grouping. Two forms of spacing are common: indentation and alignment. Indentation, which may be expressed using either tabs or spaces, is used to show levels of code dependency on certain decision points and their subsequent control flow, such as conditional and loop statements. Spacing, which should not use tabs, is also used to align syntactic elements on successive lines for consistency and aesthetics.

How do you deal with logical lines of code that are too long to fit reasonably on a single physical line? Lines that are too long are hard to scan easily and, depending on where the pane cuts, can be impossible to read all at once. They need to be broken up for readability, but where should the line break appear and how should the overflow be aligned?

Line lengths can become unreasonably long, with developers soaking up any extra columns their monitor size and resolution will afford them. Line length, however, is more constrained by limits of visual perception than by limits of hardware — there are good reasons neither web designers nor print publishers present readers with blocks of text 120+ columns wide.

Simply breaking a line and adding another level of ordinary block-level indentation for the overflow creates an ad hoc layout that appears clumsy and irregular:

assignedVariable = firstTerm +
secondTerm;
targetObject.methodCall(firstArgument,
secondArgument);

Introducing a long-distance relationship between code elements that form a unified whole and should be read together — such as a single expression or a single argument list — is a practice whose obvious drawbacks are matched only by its common occurrence. Code formatting should not look like the aftermath of tectonic movement. Not only is it awkward to read sheared code, but such fault lines can be error-prone. It is all too easy to miss an element stranded on (or beyond) the right-hand side of an editor window when its compatriots are to be found hugging the left-hand margin.

assignedVariableWithVeryLongNameNoOneWillReadFully = firstTerm +
secondTerm;
targetObjectWithVeryLongIdentifierName.methodCallToMethodWithLongIdentifierName(firstArgument,
secondArgument);

What is needed is a regular structure that respects the cohesiveness of its constituent parts, making code easier to grasp even when skim-reading. It is tempting and common to break the line after the first term on the right-hand side of an assignment or after the first argument of a method call, aligning the content of the next term to match its counterpart on the preceding line:

assignedVariable = firstTerm +
secondTerm;
targetObject.methodCall(firstArgument,
secondArgument);

This kind of formatting is also used for function definitions, field declarations and variable initialisations. Counterpart alignment is aesthetic and makes it easier to see the related terms together. However, the alignment applies only to an individual call, assignment, variable declaration or function definition at a time. Except by coincidence, other expressions or argument lists within the same function or across the same class or module will not share the same alignment. As it can leave the overall formatting of a source file ragged in appearance, this approach favours alignment that is narrowly localised in preference to alignment that is consistent with respect to local scopes or at file level.

More problematic, however, is the effect of change on this kind of formatting. If any of the names on the opening line change length, the subsequent spacing — and therefore the counterparts — becomes misaligned. Thus, although pleasing in the short term, this style becomes brittle in the long term.

renamed = firstTerm +
secondTerm;
targetObject.renamedMethodCall(firstArgument,
secondArgument);

If only addressed manually, the common task of identifier renaming becomes a high-maintenance burden, one demanding attention at every affected rename site in order to maintain local alignment. The alternative is that the formatting falls into (and remains in) disarray, the original care and structural intent swept aside by tides of change.

If formatting is handled automatically — and in a way that respects alignment, not just indentation — maintenance effort (or disrepair) is less of an issue, assuming consistent tooling and settings are used across a team or as part of the build. However, while formatters understand syntax, they do not necessarily understand intention, which may lead to curios and objections. Some developers might still baulk at the diff pollution for simple acts of renaming.

Therefore, place line breaks somewhere before rather than after the first term of the expression or clause to be broken up. The line following should be indented with respect to the left-hand side of the preceding line. This formatting leads to a regular layout that respects cohesion of code elements while remaining stable with respect to renaming, ensuring that all elements are aligned and the alignment is preserved.

Rather than defining a specific formatting convention, this pattern of sustainable spacing describes a desirable property for formatting conventions. Conventions that follow this pattern can be quite varied in style.

An implementation of this pattern might break immediately before a variable or expression:

assignedVariable =
firstTerm + secondTerm;
targetObject.methodCall(
firstArgument,
secondArgument);

Or it might break before an operator or separator:

assignedVariable
= firstTerm + secondTerm;
targetObject
.methodCall(
firstArgument, secondArgument);

And so on.

Code formatting that follows sustainable spacing is more resilient, with the format preserved in the presence of renaming, and no further automatic or manual adjustment needed.

renamed =
firstTerm + secondTerm;
targetObject.renamedMethodCall(
firstArgument,
secondArgument);

Because spacing is independent of identifier lengths, sustainable space side-steps issues of having intentional inter-line alignment of variables or expressions drift, or of amplifying the effect of renaming in diffs.

renamed
= firstTerm + secondTerm;
targetObject
.renamedMethodCall(
firstArgument, secondArgument);

In terms of vertical screen real estate, the number of lines used by this approach will be the same as or greater than other styles. Horizontally, the columns spanned may be more or less. The code has a slightly more compact appearance and is more consistently placed with respect to the left-hand side of the screen. Overall, the eye is drawn to — and distracted by — fewer vertical alignments than with other styles.

Applying sustainable space consistently implies that additional spacing between elements on a line for alignment between lines, such as matching up variable or type names in columns, should be eschewed in favour of a simple space. Although such alignment has some local aesthetic appeal, it is not implicitly sustainable and should be considered less of a priority than preserving low-maintenance consistency and a more global aesthetic.

The desire to align across many lines of similar form can sometimes highlight a different issue: either there is repetition that should be refactored or, in the case of declarations, rather than bunching together at the top of a block, each declaration should be moved to just before the point of first use and to where a variable can be initialised fully.

This pattern was first written up, presented and discussed as an example pattern at the Pattern Languages of Tandberg event in Oslo, December 2009. My thanks to those who gave their feedback on the original draft, from which this write-up has evolved. Some discussion of layout robustness on the accu-general mailing list in August 2010 helped to reinforce a couple of points and highlight a couple of omissions. This pattern was then published in CVu, January 2011. The version presented here has been further expanded and refined.

Press enter or click to view image in full size
PLoT, December 2009

The pattern form — the structure and style of the text — is based on the Alexandrian form, named for the form used by Christopher Alexander in his original pattern writings. It flows from context to problem to solution, with forces and options explored after the initial problem statement, and details and consequences after the initial solution statement. We used this form in A Pattern Language for Distributing Computing, and discussed it and other pattern forms in detail in On Patterns and Pattern Languages.

By coincidence, Alexandrian form was also the original form Michael Nygard used for architecture decision records (ADRs). Coincidence, because the pattern mining at PLoT was similar in intent to ADRs: capture and communicate in-house design expertise and decisions.

Kevlin Henney
Kevlin Henney

Written by Kevlin Henney

consultant · father · husband · itinerant · programmer · speaker · trainer · writer