What is a data clump and when does EK9 detect it?
← Code Quality · Ref: Q730
A data clump is a group of parameters that always appear together across multiple callables. EK9 detects data clumps when 3 or more functions share 4 or more matching parameters.
THRESHOLD
- Minimum shared parameters: 4
- Minimum callables sharing them: 3
WHY DATA CLUMPS ARE A PROBLEM
This is a DESIGN problem, not a technical one:
1. Maintenance burden: changing the group requires updating every callable that uses it
2. Missing abstraction: parameters that always travel together are a type waiting to be extracted
3. Inconsistency risk: one function might swap parameter order, causing subtle bugs
4. Testing complexity: 4+ parameters create a combinatorial explosion of test cases
THE FIX
Extract the repeated parameter group into a record:
// Before (data clump): // formatAddress(street, city, state, zip) // validateAddress(street, city, state, zip) // normalizeAddress(street, city, state, zip) // After (extracted record): // formatAddress(address as Address)
THIS EXAMPLE
The code below has only 2 functions sharing 4 parameters. This is below the threshold of 3 callables. A third function using the same parameter group would trigger E11053.
See Q310 for code quality overview. See Q322 for quality enforcement. See Q696 for complexity limits.
Example
defines module qa.codequality.dataclumpboundary defines function <?- First function using the address parameter group. Having 2 functions with the same 4 parameters is allowed. -?> formatAddress() as pure -> streetLine as String cityName as String regionName as String postalCode as String <- formatted as String: `${streetLine}, ${cityName}, ${regionName} ${postalCode}` <?- Second function using the same address parameter group. Still below the threshold of 3 callables. -?> validateAddress() as pure -> streetLine as String cityName as String regionName as String postalCode as String <- isValid as Boolean: false if streetLine? and cityName? and regionName? and postalCode? isValid: length streetLine > 0 and length postalCode > 0 <?- Third function with DIFFERENT parameters. This does NOT form a data clump because the parameters differ. -?> processOrder() as pure -> orderDetail as String <- processed as String: orderDetail defines program DataClumpBoundaryDemo() stdout <- Stdout() formatted <- formatAddress(streetLine: "123 Main St", cityName: "Springfield", regionName: "IL", postalCode: "62701") stdout.println(formatted) isValid <- validateAddress(streetLine: "123 Main St", cityName: "Springfield", regionName: "IL", postalCode: "62701") stdout.println(`Valid: ${isValid}`) processed <- processOrder("ORD-001") stdout.println(processed)
Common mistakes
E06270 — Adding a third function with the same 4 parameters (streetLine, cityName, regionName, postalCode) creates a data clump detected by E06270. Extract these parameters into an Address record. See ek9 -h E06270 for details.
Incorrect:
processOrder() as pure -> streetLine as String cityName as String regionName as String postalCode as String <- processed as String: streetLine
Correct:
processOrder() as pure -> orderDetail as String <- processed as String: orderDetail
Other ways to ask this
- What triggers E11053 data clump detected?
- How many functions sharing parameters trigger a data clump?
- What is the data clump threshold?
- Why does EK9 enforce the data clump rule?
Coming from another language?
Java: no built-in data clump detection (PMD and SonarQube can detect, optional). Python: no detection. C++: no detection. Rust: no detection (tuples and structs discourage clumps). Go: no detection. EK9: compile-time data clump detection, cannot be suppressed.
Keywords: record, threshold, refactoring, data, E11053, parameter, extract, clean-code, clump, quality, limit, boundary, Fowler