How does EK9 detect confusingly similar variable names?

← Code Quality · Ref: Q764

EK9 checks for variables of the same type in the same scope whose names differ by only a single character edit, or by case alone (a weighted Levenshtein distance of 2 or less, where one character edit costs 2 and a case change costs 1). When detected, E11030 triggers.

WHAT IT DETECTS

Two variables like 'count' and 'coumt' differ by one character — a typo waiting to happen. Similarly 'index' and 'indx' or 'total' and 'totl'. When a developer (or AI) references the wrong one, the bug is subtle and hard to spot.

WHAT IS ALLOWED

- Names differing by two or more character edits are fine ('counter' and 'count', 'totalCount' and 'totalCoxyt')
- Names shorter than 3 characters are not checked
- Prefixed/suffixed variants are fine: 'name' and 'firstName'
- Single-letter names in loop context: 'i', 'x', 'y'
- Different scopes: same-name variables in different functions

THIS EXAMPLE

The function below uses 'totalCount' and 'itemCount' — these differ by far more than one character edit, so they are clearly distinguishable. Using 'totalCount' and 'totalCoumt' (one character substituted) would trigger E11030.

WHY THIS MATTERS

- AI assistants generate code at speed — similar names cause subtle bugs
- Code review misses single-character differences
- Autocomplete in editors may pick the wrong variable
- Debugging similar-name bugs wastes significant time

See Q290 for banned names. See Q292 for naming conventions. See Q310 for quality overview.

Example

defines module qa.codequality.similarnames

  defines function

    <?-
      This function uses clearly distinct variable names.
      'totalCount' and 'itemCount' differ by enough characters
      to be clearly distinguishable (far more than one character edit apart).
      Using 'totalCount' and 'totalCoumt' would trigger E11030.
    -?>
    calculateTotals()
      ->
        items as List of Integer
      <-
        result as String: "empty"

      totalCount <- 0
      itemCount <- 0
      grandTotal <- 0

      for item in items
        itemCount++
        totalCount++
        grandTotal += item

      result: `Items: ${itemCount}, Count: ${totalCount}, Total: ${grandTotal}`

  defines program

    SimilarNamesBoundaryDemo()
      stdout <- Stdout()
      numbers <- [10, 20, 30, 40, 50]
      stdout.println(calculateTotals(numbers))

Common mistakes

E11030 — Renaming 'itemCount' to 'totalCont' makes it confusingly similar to 'totalCount' (the compiler reports 'distance 2', its weighted score for one character edit). Both are used in the same scope, creating risk of referencing the wrong one. Use clearly distinct names. See ek9 -h E11030 for details.

Incorrect:

      totalCount <- 0
      totalCont <- 0
      grandTotal <- 0

      for item in items
        totalCont++
        totalCount++
        grandTotal += item

      result: `Items: ${$totalCont}, Count: ${$totalCount}, Total: ${$grandTotal}`

Correct:

      totalCount <- 0
      itemCount <- 0
      grandTotal <- 0

      for item in items
        itemCount++
        totalCount++
        grandTotal += item

      result: `Items: ${itemCount}, Count: ${totalCount}, Total: ${grandTotal}`
Other ways to ask this
  • What triggers E11030 similar names?
  • Why does EK9 flag variables with similar names?
  • How close can variable names be in EK9?
  • What is the edit distance check for names?

Coming from another language?

Java: no similar-name detection. C#: no similar-name detection. Python: no similar-name detection. Go: no similar-name detection. Rust: no similar-name detection. All languages rely on code review to catch confusingly similar names. EK9: same-typed names a single character edit apart in one scope are a compiler error.

Keywords: similar, typo, quality, E11030, distance, Levenshtein, naming, confusing, names, variable