E11013: excessive expression complexity - extract intermediate variables

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

What went wrong

Deeply NESTED coalescing operators exceed complexity threshold. Note: Multiple INDEPENDENT coalescing operators are fine. A chain nests, so it may hold at most 3 of ?: - or 2 of <? >? - at any length.

There is also a hard limit on any ONE expression: at most 20 operators and at most 20 member accesses ('.'). An expression ends at a comma or at the end of its statement (a line ending in a binary operator carries on). One beyond either is reported here - "21 operators in one expression - the limit is 20" - when the source is read, before it is parsed, and nothing else in that file is reported until it is fixed. Real code uses at most 15 operators and 7 member accesses in an expression.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 1302 (Why does EK9 reject a single deeply-nested coalescing exp...)

Rationale

  • Each level of nesting multiplies what a reader must hold in mind
  • EK9 counts each operator at 3^(depth-1) of its base cost, so 3 levels = 9x
  • The refactored version produces IDENTICAL results

How to fix it

  1. Extract intermediate variables for nested coalescing expressions
  2. Break complex expression into multiple simple statements
  3. Name part of a long expression or chain - 'subtotal <- ...' - and use the name in the rest

Common causes

  • Deeply NESTED coalescing operators (?:, <?, >?)
  • Multiple coalescing within parentheses inside other coalescing
  • A long arithmetic or boolean formula written as one expression
  • A long chain of method calls: a.b().c().d()...

See also

  • E11013: expression complexity (this error)
  • E11010: cyclomatic complexity

Examples

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

Fails with E11013: excessive expression complexity - extract intermediate variables

#!ek9
defines module error.e11013.bad

  defines function

    chosen()
      ->
        first as Integer
        second as Integer
        third as Integer
        fourth as Integer
      <- rtn as Integer: ((first ?: second) <? third) >? fourth

Fixed: Name the intermediate values

#!ek9
defines module error.e11013.good

  defines function

    chosen()
      ->
        first as Integer
        second as Integer
        third as Integer
        fourth as Integer
      <- rtn as Integer?

      available <- first ?: second
      lower <- available <? third
      rtn: lower >? fourth

Questions and answers

These Q&A entries show E11013 and its fix: