E11030: confusingly similar variable names - rename for clarity

Category: E11xxx Code quality and IR analysis · Reported in phase: PRE_IR_CHECKS · Classification: CONFUSINGLY_SIMILAR_NAMES · All error codes

What went wrong

Two names of the same type, in reach of each other, are one edit apart, or differ only in case. This creates confusion and increases bug risk when you (or an AI assistant) reference the wrong variable.

Research basis

  • Aman et al., Empirical Software Engineering (2023): of about 117 million pairs of compound variable names in 1,876 Java projects, about a million (0.86%) were confusingly similar in both spelling and meaning.
  • Wong et al., "Identifier Name Similarities: An Exploratory Study" (arXiv 2025): names that are the same or similar but differ in purpose "can confuse developers, resulting in potential bugs, increased cognitive load, and loss of productivity".

Why same-type matters

If types differ, the compiler catches most mistakes. With same types, errors are silent: a 'customerName' and a 'customerNames' that are both String are one character apart, and either can be passed where the other was meant.

PATTERNS DETECTED (same type, one edit apart):

  • One edit: ONE character inserted, removed or changed - anywhere, the first and last positions included (data/dat, userId/usersId, count/coumt, qname/name) - or two ADJACENT characters swapped (title/titel), anywhere but the first two letters
  • A difference of case alone, however many letters (total/Total, userID/userid): nothing in the spelling tells such names apart, so no exemption below applies to them
  • Similar locals: two locals of one method, function or operator
  • Similar parameters: userId/usersId in one signature
  • Parameter or local similar to a property of its type: parameter 'usersId' or local 'dat' beside property 'userId' or 'data'
  • Similar properties: two properties of one class, record, component or dynamic class (userId/usersId) - reported on the type

PATTERNS ALLOWED (not errors):

  • Different types: data (String) vs date (Date) - type system catches misuse
  • The same name: a constructor parameter 'userId' that sets property 'userId', or one name declared again in another block
  • Two or more edits: two characters added, at the start or the end (count/account, port/export, count/countxq), or two characters changed
  • The first two letters swapped (latitude/altitude): such pairs are usually two different words, so a swap there is not counted as one edit
  • Names shorter than 3 characters (i, j, x, y)
  • Loop variables
  • Numbered variants: value1/value2, keys1A/keys2A, keys1/keys1A
  • A distinguishing prefix: valid/invalid, used/unused, process/preprocess, aList/bList, xPos/yPos
  • A distinguishing suffix: user/userId, data/dataRaw, initialX/initialY
  • A property of a super type: only the type's own properties are compared

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 764 (How does EK9 detect confusingly similar variable names?)

How to fix it

  • Rename one variable to be more distinct
  • Use more descriptive names: 'customerData' vs 'orderDate'
  • Consider if you actually need both variables

Transform

The [EXAMPLE] section below shows two variables of one type whose names differ by a character or two, and the same code with distinct names that say what each holds.

Why this helps AI assistants

AI assistants process code token-by-token without spatial memory. Similar names compete in attention mechanisms, causing AI to reference the wrong variable. Distinctive names improve AI code generation quality.

THRESHOLD: one edit with the same type. The message's 'distance' is the weighted edit distance: a character inserted, removed or changed costs 2 wherever it is, a swap of two adjacent characters costs 2 (a swap of the first two letters is two changes, 4), a change of case costs 1. A pair is reported at distance 2 or less (one edit, or one or two case changes), and always when the names differ only in case.

See also

  • E01030: duplicate name (Variable/Function/Type)
  • E11031: non-descriptive variable name

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E11030: confusingly similar variable names - rename for clarity

#!ek9
defines module error.e11030.bad

  defines function

    similarLocalVariables()
      <- result as String: ""

      userName <- "customer data"
      userNam <- "other data"
      result: userName + userNam

Fixed: Give the variables names that differ in meaning, not by a letter

#!ek9
defines module error.e11030.good

  defines function

    distinctNames()
      <- result as String: ""
      customerName <- "customer data"
      supplierName <- "other data"
      result: customerName + supplierName

Questions and answers

These Q&A entries show E11030 and its fix: