Why does EK9 enforce a single standard format?

← Code Formatting · Ref: Q625

EK9 enforces a single canonical format for the same reason Go does with gofmt: formatting debates are a waste of engineering time.

THE GOFMT PRINCIPLE

Go's gofmt proved that a single, non-configurable formatter eliminates an entire category of team friction. Before gofmt, Go teams argued about brace placement, tab width, and blank lines. After gofmt, every Go file looks the same. The debate simply vanished.

EK9 APPLIES THE SAME LOGIC

The EK9 formatter produces one canonical output. There are no configuration flags for indent size, brace style, or line length. This is a deliberate design decision, not a missing feature.

BENEFITS

1. Zero formatting debates in code reviews. Every file looks identical.
2. Diffs show only semantic changes, never whitespace noise.
3. AI-generated code matches human-written code exactly.
4. New team members produce correctly-formatted code from day one.
5. Merge conflicts from formatting differences are eliminated.

THIS IS PART OF THE VERTICAL INTEGRATION

EK9 collapses 15+ external tools into the compiler. The formatter is one of them. Instead of configuring prettier, ESLint, editorconfig, and pre-commit hooks separately, EK9 provides ek9 -f built into the same binary that compiles, tests, and packages your code.

See Q622 for formatting a single file. See Q623 for formatting all project files. See Q310 for quality checks at compile time. See Q16 for indentation rules.

Example

defines module qa.codeformatting.whystandard

  defines class

    <?-
      A class written in canonical EK9 format.
      Every developer's version of this class looks identical
      after formatting because there is only one style.
    -?>
    Temperature
      degrees as Float: 0.0
      scale as String: "C"

      Temperature()
        ->
          initialValue as Float
          initialScale as String
        degrees: initialValue
        scale: initialScale

      toCelsius() as pure
        <- result as Float: degrees

      toDisplay() as pure
        <- result as String: `${degrees} ${scale}`

      operator $ as pure
        <- result as String: toDisplay()

      default operator ?

  defines program

    WhyStandardFormatDemo()
      stdout <- Stdout()

      boiling <- Temperature(100.0, "C")
      stdout.println($boiling)

Common mistakes

E50060 — Temperature has no toString() method. Use the $ prefix operator for string conversion. See ek9 -h E50060 for details.

Incorrect:

stdout.println(boiling.toString())

Correct:

stdout.println($boiling)

E50060 — Float has no intValue() method in EK9. Use explicit conversion if needed. See ek9 -h E50060 for details.

Incorrect:

boiling <- Temperature(100.0, "C").toCelsius().intValue()

Correct:

boiling <- Temperature(100.0, "C")
Other ways to ask this
  • Why can I not configure the EK9 formatter?
  • Why does EK9 have only one formatting style?
  • What is the benefit of a non-configurable formatter?

Coming from another language?

Go: gofmt established the 'one true format' principle. No configuration, universally adopted. Rust: rustfmt has some configuration options but defaults are strongly encouraged. Python: black is 'the uncompromising formatter' (few options). Java: teams still argue about google-java-format vs checkstyle vs IntelliJ defaults. JavaScript: prettier has some configuration. EK9: follows gofmt philosophy exactly, zero configuration, one canonical format.

Keywords: migrate, style, debate, opinionated, team, indent, convention, configure, format, gofmt, standard, canonical