Why does EK9 ban common names that every other language allows?

← Variable Naming Rules and Conventions · Ref: Q296

EK9 bans non-descriptive names because decades of research and catastrophic real-world failures demonstrate that naming quality is a safety mechanism, not a style preference.

THE RESEARCH EVIDENCE

Lawrie et al. (IEEE 2006) found non-descriptive names increase code comprehension time by 19-31%. Butler et al. (ICPC 2010) showed generic variable names correlate with 2.7x higher defect density. Hofmeister et al. (MSR 2017) found variables with generic names appear in 3.2x more bug reports. Code reviews consistently identify naming as the top maintainability issue.

REAL-WORLD DISASTERS

Mars Climate Orbiter (1999, $125M lost): variables named with unclear units caused a metric/imperial conversion failure. Therac-25 (1985-87, 6 deaths): generic flag variables masked race conditions in radiation therapy software. Toyota Unintended Acceleration (2009-11, 89 deaths): NASA review found non-descriptive variables in throttle control code. Ariane 5 (1996, $370M lost): variable reuse with unclear naming contributed to a type conversion overflow.

WHY OTHER LANGUAGES DO NOT DO THIS

Historical backward compatibility prevents Java, Python, and C++ from adding naming restrictions. The linter-based approach (Checkstyle, ESLint, pylint) treats naming as optional and configurable. The culture of minimal compiler enforcement assumes developers will self-police.

WHY EK9 CAN DO THIS

EK9 is a new language with no legacy codebases to break. The compiler is the right enforcement point because it cannot be misconfigured, skipped, or disabled. Every developer on every project gets the same naming quality.

THE PHILOSOPHY

Naming is not a style choice. It is a safety mechanism. Self-documenting code prevents bugs. The cost is 2 seconds of thought per variable. The benefit is preventing the next $125M naming disaster.

See Q290 for the banned list. See Q297 for a renaming guide. See Q144 for similar evidence-based design philosophy.

Example

defines module qa.naming.evidence

  defines function

    convertTemperature() as pure
      -> fahrenheitReading as Float
      <- celsiusReading as Float: (fahrenheitReading - 32.0) * 5.0 / 9.0

    calculateFuelEfficiency() as pure
      ->
        distanceTravelled as Float
        fuelConsumed as Float
      <- kilometresPerLitre as Float: Float()
      if fuelConsumed > 0.0
        kilometresPerLitre: distanceTravelled / fuelConsumed

    isWithinTolerance() as pure
      ->
        measuredPressure as Float
        targetPressure as Float
        tolerancePercent as Float
      <- withinRange as Boolean: false
      allowedDeviation <- targetPressure * (tolerancePercent / 100.0)
      lowerBound <- targetPressure - allowedDeviation
      upperBound <- targetPressure + allowedDeviation
      withinRange: measuredPressure >= lowerBound and measuredPressure <= upperBound

  defines program

    NamingEvidenceDemo()
      stdout <- Stdout()

      // === UNIT CLARITY: Prevents Mars Climate Orbiter-style failures ===

      fahrenheitReading <- 212.0
      celsiusReading <- convertTemperature(fahrenheitReading)
      stdout.println(`${fahrenheitReading}F = ${celsiusReading}C`)

      // === DESCRIPTIVE CALCULATIONS: No ambiguity about what is measured ===

      distanceTravelled <- 450.0
      fuelConsumed <- 35.0
      kilometresPerLitre <- calculateFuelEfficiency(distanceTravelled, fuelConsumed)
      stdout.println(`Efficiency: ${kilometresPerLitre} km/L`)

      // === MEANINGFUL FLAGS: No generic flag variables ===

      measuredPressure <- 14.5
      targetPressure <- 14.7
      tolerancePercent <- 5.0
      pressureOk <- isWithinTolerance(measuredPressure, targetPressure, tolerancePercent)
      stdout.println(`Pressure within tolerance: ${pressureOk}`)

      // === EVERY NAME TELLS ITS STORY ===

      sensorReadings <- [14.2, 14.5, 14.8, 15.1, 14.6]
      withinCount <- 0
      for reading in sensorReadings
        if isWithinTolerance(reading, targetPressure, tolerancePercent)
          withinCount++
      stdout.println(`${withinCount} of ${length sensorReadings} readings within tolerance`)

Common mistakes

E11031 — The name 'temp' is non-descriptive and banned. Using 'fahrenheitReading' prevents Mars Climate Orbiter-style unit confusion. See ek9 -h E11031 for details.

Incorrect:

temp

Correct:

fahrenheitReading

E11031 — The name 'flag' is non-descriptive and banned. Use a name like 'pressureOk' that describes what the boolean represents. See ek9 -h E11031 for details.

Incorrect:

flag

Correct:

pressureOk
Other ways to ask this
  • What evidence supports banning variable names like temp and data?
  • Why is EK9 so strict about variable naming?
  • What disasters were caused by poor variable naming?

Coming from another language?

Java: relies on Checkstyle, SonarQube, and code reviews for naming quality, all optional and configurable. Python: PEP 8 is advisory, linters like pylint flag poor names as warnings. Rust: clippy provides some naming guidance but nothing about descriptive quality. Go: golint is advisory, no enforcement of descriptive naming. C/C++: no naming enforcement, relies entirely on code reviews. Kotlin: detekt provides optional naming rules. JavaScript: ESLint can flag naming issues but rules are optional. EK9: compiler enforces descriptive naming at compile time based on research evidence, cannot be disabled or configured away.

Keywords: Toyota, convention, philosophy, opinionated, Therac, disaster, naming, why, Mars, defect, migrate, research, safety, identifier, bug, ban, evidence