How does EK9 measure complexity?
← Code Quality · Ref: Q312
EK9 measures complexity using five metrics, all enforced at compile time. Exceeding any threshold is a compilation error, not a warning.
CYCLOMATIC COMPLEXITY (E11010)
Measures the number of independent paths through a function. Each if, else if, while, for, switch case, and guard adds one. Threshold: 45. Based on McCabe 1976 research showing defect rate increases sharply above this level.
NESTING DEPTH (E11011)
Measures the deepest level of nesting in a function. Each nested if, for, while, switch, or try adds one level. Threshold: 6. Deep nesting correlates with bugs because humans lose track of context beyond 3-4 levels.
STATEMENT COUNT (E11012)
Counts executable statements in a function. Long functions are harder to understand, test, and modify. The threshold encourages decomposition into smaller, focused functions.
COMBINED COMPLEXITY (E11020)
A product formula combining cyclomatic complexity, nesting depth, and statement count. This catches functions that are individually below each threshold but collectively too complex. A function with 40 cyclomatic, 5 nesting, and high statements can still be flagged.
COGNITIVE COMPLEXITY (E11021)
Measures how hard code is to understand, not just how many paths exist. Cognitive complexity penalises nesting more heavily than flat structures. A deeply nested if-else chain scores higher than the same logic refactored into flat guard expressions. Threshold: 35.
WHAT ADDS COMPLEXITY
Each of these adds to complexity:
- if/else if/else branches
- for/while loops
- switch cases
- try/catch handlers
- guard expressions (but less than nested ifs)
- Boolean operators in conditions
DECOMPOSITION PATTERN
When a function is too complex, extract helper functions. Each extracted function has its own complexity budget. This is exactly the decomposition that EK9 philosophy encourages.
See Q311 for the full quality checks catalog. See Q313 for code smell detection. See Q146 for decomposition over return. See Q630 for identifying hot methods via profiling.
Example
defines module qa.codequality.complexity defines function <?- A well-decomposed function stays within complexity thresholds. Each helper handles one concern with low individual complexity. -?> isWeekday() as pure -> dayNumber as Integer <- rtn as Boolean: false mondayIndex <- 1 fridayIndex <- 5 if dayNumber >= mondayIndex and dayNumber <= fridayIndex rtn: true describeDayType() as pure -> dayNumber as Integer <- description as String: "weekend" if isWeekday(dayNumber) description: "weekday" formatDayReport() as pure -> dayName as String dayNumber as Integer <- report as String: "" dayType <- describeDayType(dayNumber) report: `${dayName} is a ${dayType}` defines program ComplexityMetricsDemo() stdout <- Stdout() mondayNumber <- 1 saturdayNumber <- 6 mondayReport <- formatDayReport("Monday", mondayNumber) saturdayReport <- formatDayReport("Saturday", saturdayNumber) stdout.println(mondayReport) stdout.println(saturdayReport)
Common mistakes
E50001 — Renaming the variable means later references to 'mondayNumber' become unresolved, triggering E50001. See ek9 -h E50001 for details.
Incorrect:
mondayNumberXYZ <- 1
Correct:
mondayNumber <- 1
E50001 — Renaming the variable means later references become unresolved, triggering E50001. See ek9 -h E50001 for details.
Incorrect:
mondayReportXYZ <- formatDayReport("Monday", mondayNumber)
Correct:
mondayReport <- formatDayReport("Monday", mondayNumber)
Other ways to ask this
- What complexity metrics does EK9 use?
- How does EK9 calculate cyclomatic complexity?
- What is cognitive complexity in EK9?
Coming from another language?
Java: SonarQube measures cyclomatic and cognitive complexity but as optional warnings. PMD has CyclomaticComplexity rule but configurable threshold. Rust: no built-in complexity measurement, clippy has cognitive_complexity lint (allow by default). Go: gocyclo is a third-party tool, not built-in. Python: radon measures complexity but is a separate optional tool. EK9: all five complexity metrics built into the compiler as mandatory errors with fixed thresholds.
Keywords: cyclomatic, E11011, E11010, complexity, quality, nesting, metrics, metric, depth, mccabe, cognitive, threshold, clean-code, E11020, E11021