E11031: non-descriptive variable name - use meaningful identifier

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

What went wrong

The variable name is non-descriptive and provides minimal semantic information. Generic names like 'temp', 'flag', 'data' mask the actual purpose of the variable, making code harder to understand and maintain.

The banned names (case-insensitive): temp, tmp, flag, flg, data, dat, object, obj, value, val, buffer, buf, arg (and arg0, arg1, ...).

This applies to every variable: locals, parameters, fields and a NAMED capture '(temp: 7)' in a dynamic function or class, which is a new variable too.

'arg', 'arg0', 'arg1', ... are banned too: they name a POSITION, not a role. A parameter name is published API - a labelled call must spell it (E06250) and four or more arguments must be labelled (E11062) - so 'arg0' would become the mandated spelling at every call site.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 922 (Why does my EK9 code fail with E11031 when I use 'data...)
  • ek9 -q 291 (Why does the compiler reject my variable name?)
  • ek9 -q 290 (What variable names are banned in EK9?)
  • ek9 -q 925 (How do I name class fields without triggering E11031?)
  • ek9 -q 292 (What are the naming conventions for variables in EK9?)
  • ek9 -q 296 (Why does EK9 ban common names that every other language a...)

Rationale

Academic studies show that non-descriptive variable names cost readers time:

  • Full-word identifiers were understood better than single letters (Lawrie et al., ICPC 2006)
  • Flawed identifier names went with lower-quality code (Butler et al., CSMR 2010)
  • Defects were found about 19% faster when identifiers were words rather than letters or abbreviations (Hofmeister et al., SANER 2017)

High-profile failures involved values whose meaning was not in the code:

  • Mars Climate Orbiter (1999): an impulse in pound-force seconds read as newton-seconds
  • Therac-25 (1985-87): a one-byte counter that wrapped to zero skipped a safety check

How to fix it

Replace the generic name with a name describing WHAT the variable represents:

Banned -> use instead:

  • temp, tmp -> temporaryUser, calculationResult
  • flag, flg -> isValid, hasPermission, wasProcessed
  • data, dat -> customerData, configData, requestPayload
  • object, obj -> user, order, session
  • value, val -> price, count, threshold
  • buffer, buf -> inputBuffer, responseBuffer
  • arg -> other, item, amount, message

Strong typing

EK9's type system reduces naming burden when using specific types: 'amount' declared as Money, or 'thrust' as a Dimension, carries its meaning in its type. The same names declared as a bare Float say nothing about what they measure - prefer 'paymentAmount' or 'thrustNewtons' there.

What is not banned

Only the names listed above are banned (and 'arg' followed by digits). Short mathematical names ('x', 'y', 'r', 'theta'), loop counters ('i', 'j') and compound names that contain a banned word ('tempCelsius', 'customerData') are all fine (good_allowed.ek9 in the [EXAMPLE] section below):

//Mathematical names
x <- 3.5
y <- 2.0
r <- sqrt (x * x + y * y)
//Loop counters
total <- 0
for i in 1 ... 3
  for j in 1 ... 2
    total += i * j
//A banned word inside a compound name
tempCelsius <- 21.5
customerData <- "Steve"

Ai comprehension

Meaningful names reduce AI token usage and improve accuracy. Generic names force AI assistants to search backward for declarations and forward for uses to infer purpose, consuming significant tokens.

Academic references

  • Lawrie et al. (2006): "What's in a Name? A Study of Identifiers" IEEE ICPC
  • Butler et al. (2010): "Exploring the Influence of Identifier Names on Code Quality" CSMR
  • Hofmeister et al. (2017): "Shorter Identifier Names Take Longer to Comprehend" SANER

See also

https://ek9.io/quality.html#naming-quality https://ek9.io/forAI.json#$.bannedIdentifiers

Examples

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

Fails with E11031: non-descriptive variable name - use meaningful identifier

#!ek9
defines module error.e11031.bad

  defines function

    process1()
      <- result as String: ""
      temp <- "mainValue"
      result: temp

    process2()
      <- result as Boolean: false
      flag <- true
      result: flag

    process3()
      <- result as String: ""
      data <- "info"
      result: data

    process4()
      <- result as Integer: 0
      value <- 42
      result: value

    process5()
      <- result as String: ""
      obj <- "something"
      result: obj

    process6()
      <- result as String: ""
      buf <- ""
      result: buf

    process7()
      ->
        tmp as String
      <-
        result as String: ""

      result: tmp

    process8()
      ->
        val as Integer
      <-
        result as Integer: 0

      result: val

Fixed: Rename each one to say what it holds

#!ek9
defines module error.e11031.good.fix

  defines function

    process1()
      <- result as String: ""
      mainText <- "mainValue"
      result: mainText

    process2()
      <- result as Boolean: false
      ready <- true
      result: ready

    process3()
      <- result as String: ""
      info <- "info"
      result: info

    process4()
      <- result as Integer: 0
      answer <- 42
      result: answer

    process5()
      <- result as String: ""
      something <- "something"
      result: something

    process6()
      <- result as String: ""
      emptyText <- ""
      result: emptyText

    process7()
      ->
        input as String
      <-
        result as String: ""

      result: input

    process8()
      ->
        amount as Integer
      <-
        result as Integer: 0

      result: amount

Fixed: Name what the value is for

#!ek9
defines module error.e11031.good

  defines function

    greetingFor()
      -> customerName as String
      <- greeting as String: String()
      salutation <- "Hello, "
      greeting: salutation + customerName

    isAdult()
      -> ageInYears as Integer
      <- adult as Boolean?
      adultAge <- 18
      adult: ageInYears >= adultAge

Fixed: Only the listed names are banned: short mathematical names, loop counters and compounds are fine

#!ek9
defines module error.e11031.good.allowed

  defines function

    radius()
      <- rtn as Float?
      //Mathematical names
      x <- 3.5
      y <- 2.0
      r <- sqrt (x * x + y * y)
      //Loop counters
      total <- 0
      for i in 1 ... 3
        for j in 1 ... 2
          total += i * j
      //A banned word inside a compound name
      tempCelsius <- 21.5
      customerData <- "Steve"
      rtn: r + #^total + tempCelsius + #^length customerData

Fixed: A specific type carries the meaning; a bare type needs a descriptive name

#!ek9
defines module error.e11031.good.typed

  defines function

    //Money says what each value is, so a short name reads well
    totalPaid()
      ->
        amount as Money
        fee as Money
      <- total as Money: amount + fee

    //A bare Float says nothing about what it holds: the name has to
    totalPaidInPounds()
      ->
        paymentAmount as Float
        feeAmount as Float
      <- total as Float: paymentAmount + feeAmount

Questions and answers

These Q&A entries show E11031 and its fix: