E11053: data clump detected - extract a record to group repeated parameters

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

What went wrong

Three or more callables (functions, methods, or constructors) in this module share 4+ parameters with matching types and similar names. This repeated parameter group is a "data clump" that should be extracted into a record.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 855 (Why does EK9 reject repeated parameter groups across fu...)
  • ek9 -q 962 (What is a data clump and how does EK9 detect it?)
  • ek9 -q 313 (How does EK9 detect code smells?)
  • ek9 -q 311 (What code quality checks does the EK9 compiler perform?)

Rationale

  • Fowler (1999): Data clumps are a code smell - parameters that always travel together should be encapsulated in their own type
  • Reduces parameter count, improving readability and maintainability
  • A record provides a single point of change when the group evolves
  • Prevents subtle bugs from parameter ordering mistakes
  • Threshold: 4+ shared parameters across 3+ callables

Detection details

  • Types must match exactly (by fully qualified name)
  • Names: exact match preferred, allows at most 1 fuzzy match per pairwise comparison (Levenshtein distance of 2 or less)
  • Uses Union-Find to group transitively connected signatures
  • Built-in modules (org.ek9.*) are exempt from this check

How to fix it

  1. Identify the repeated parameter group listed in the error message
  2. Create a record with those parameters as fields
  3. Replace the parameter group with a single record parameter in EVERY callable listed above - converting only some leaves the clump intact
  4. Update all call sites to construct the record, using NAMED arguments. The record's constructor takes the same 4+ parameters, so constructing it positionally just re-raises E11062 at the new call site
  5. Recompile - this error and any co-fired E11062 should both be clear

Refactor is atomic

This fix has no compiling intermediate state. The record constructor you create in order to fix the clump is itself a callable carrying the group, so a partially-applied refactor reports MORE clump members than you started with (3 callables -> 4). Only the end state is clean: once every listed callable takes the record, the constructor is the sole remaining carrier - one callable, below the 3-callable threshold.

Do not sequence this as a scaffold step followed by per-callable signature changes; the gated editors refuse each intermediate. Build the whole rewrite as one edit, then compile.

Common causes

  • Address-like data (street, city, state, zip) passed to multiple functions
  • Coordinate data (x, y, z, w) repeated across methods
  • Configuration values passed individually instead of as a config record
  • Person data (firstName, lastName, email, phone) spread across callables

See also

  • E11062: 4+ positional arguments (co-fires with this error, and RELOCATES into the record constructor unless step 4 names the arguments)
  • E11030: confusingly similar names (name-level quality)
  • E11014: low cohesion (related structural quality metric)

Examples

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

Fails with E11053: data clump detected - extract a record to group repeated parameters

#!ek9
//Module-level error: 3 functions share 4 identical parameters (street, city, state, zipCode)
defines module error.e11053.bad

  defines function

    formatAddress()
      ->
        street as String
        city as String
        state as String
        zipCode as String
      <- result as String: `${street}, ${city}, ${state} ${zipCode}`

    validateAddress()
      ->
        street as String
        city as String
        state as String
        zipCode as String
      <- valid as Boolean: street? and city? and state? and zipCode?

    normalizeAddress()
      ->
        street as String
        city as String
        state as String
        zipCode as String
      <- result as String: `${street.upperCase()}, ${city.upperCase()}, ${state.upperCase()} ${zipCode}`

Fixed: Group the parameters that always travel together into a record

#!ek9
defines module error.e11053.good

  defines record

    Address
      street as String: String()
      city as String: String()
      state as String: String()
      zipCode as String: String()

      default operator ?

  defines function

    formatAddress()
      -> address as Address
      <- result as String: `${address.street}, ${address.city}, ${address.state} ${address.zipCode}`

    validateAddress()
      -> address as Address
      <- valid as Boolean: address?

Questions and answers

These Q&A entries show E11053 and its fix: