20 January 2026

Coding Style: Formatter barrier

FORMATTER BARRIER
Trailing line comment (//) can be used as a formater barrier to prevent automated formaters or IDEs from collapsing or reflowing long fluent chains. This convention has been used successfully in production codebases for more than decade, including in large and continuously evolving systems, without causing semantic issues or tooling problems. Its primary benefit is preserving the visual structure of code across edits and refactoring, which significantly improves readability, code review quality, and long-term maintainability; it also helps reviewers more easily identify flawed logic or misunderstandings during code review. Maintaining a stable visual layout supports developers (especially those who rely on visual patterns when reading and reasoning about code) in recognizing intent, spotting inconsistencies, and retaining structural understanding even after substantial changes. This practice affects only formatting, has no impact on compilation or runtime behavior.
Tools already treats comments as layout anchors!

Just compare:
public static <D extends IcdCodeGet & Comparable<D>, L extends IcdListAccess & Comparable<L>> IcdCodeGet[] getBestCodes( //
      ComparableList<ComparableLink<L, IcdCodeGet[]>> bests //
      , L list //
      , boolean renew //
      , ExtendedIterator<CounterCmp<D>> statsSource) {...}
with:
public static <D extends IcdCodeGet & Comparable<D>, L extends IcdListAccess & Comparable<L>> IcdCodeGet[] getBestCodes( ComparableList<ComparableLink<L, IcdCodeGet[]>> bests, L list, boolean renew, ExtendedIterator<CounterCmp<D>> statsSource) {...}
This gives us freedom to auto colapse arguments and uncollapse them manually when needed.
ORIGIN
Once we move away from prehistoric code and start writing modern software using meaningful names, expressive types, generics (where appropriate), proper exceptions with explanations, and avoiding cryptic aliases — we can reach a simple conclusion:
Old line-length standards were designed for old code styles, not modern ones.

The 80-character rule made sense when:
  • identifiers were short,
  • types were shallow,
  • logic was procedural
  • and screens were literally 80 columns wide.
None of that is true anymore and modern code breaks old assumptions.
Today, reading 200–300 characters horizontally is easy on modern screens. What is not easy is forcing modern, expressive code into universal formatter rules.
If you tell a formatter to always break lines "when it seems useful", you end up with code that looks like:
a long sentence
with each word
on a new line
On the other hand if you tell it to always collapse lines, you end up with:
  • unstable blobs of code,
  • massive diffs from tiny changes,
  • and layouts that lose all semantic structure.
Example:
final AsynchronousEventStreamProcessor<
   ExtremelySpecificBusinessInvariant,
   AnotherPainfullyDescriptiveType,
   Map<String, List<Optional<Thing>>
> eventStreamProcessor =
   someFactory.create(...);

final AsynchronousEventStreamProcessor<ExtremelySpecificBusinessInvariant, AnotherPainfullyDescriptiveType, Map<String, List<Optional<Thing>>>> eventStreamProcessor = someFactory.create(...);
Both compile.
None communicates any structure - as all code will look the same.
Any universal formatting rule is horrible in one of two ways:
  • Too many breaks - only ~20% of the code is visible, no flow, no locality.
  • Too few breaks - unreadable horizontal blobs that reformat chaotically.
Trying to “fix” this has produced a collection of bad (or at least distorted) rules:
  • artificially limiting the number of parameters
  • splitting methods just to shorten names
  • using one-letter generic parameters
  • collapsing meaning to satisfy formatting tools
These rules are not always unreasonable - but they are symptoms, not solutions.

We already solved this once — but it was forgotten. Long ago, ; acted as a visual separator. Statements ended clearly. Structure was obvious.
As we moved toward:
  • fluent APIs,
  • streams,
  • method chaining,
we stopped breaking lines openly — and formatters took over.

To project structure into code, I intentionally use:
  • explicit line breaks
  • semantic grouping
  • when necessary
This way I can stop formatter from destroying information.
Breaking lines adds meaning when:
  • Parameters in declarations
    They define what a method does - split them when they carry meaning.
  • Parameters belonging to multiple logical scopes
    Break by scope - reviewers instantly see intent in diffs.
  • Large collections (e.g. 300 strings)
    Break by first character - searchable, scannable, maintainable.
  • Complex logical expressions in if statements
    Break as much as needed until logic becomes obvious.
In all these cases, formatting reduces cognitive load.
That is the main metric that matters.

Ofcourse it’s will be useless for DTO-style programming.

0 comments / komentarz(y):

Post a Comment