E01070: 'break' does not exist in EK9 - use stream pipelines with 'head' or guards

Category: E01xxx Parsing and excluded constructs · Reported in phase: SYMBOL_DEFINITION · Classification: BREAK_NOT_SUPPORTED · All error codes

What went wrong

The 'break' keyword does not exist in EK9.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 65 (How do I use a for loop to iterate over a collection?)
  • ek9 -q 64 (How do I write a for loop over a range of numbers?)
  • ek9 -q 63 (How does switch/case work in EK9?)
  • ek9 -q 68 (Can switch return a value (switch as expression)?)
  • ek9 -q 69 (How do I match multiple values in one case?)

Rationale

EK9 excludes 'break' based on 50+ years of production bug evidence:

  • Dijkstra (1968): "Go To Statement Considered Harmful" - break is a restricted jump out of the structured flow
  • In nested loops a break exits only the innermost loop; a misplaced one compiles and exits the wrong loop
  • A break omitted from a switch case falls through silently (CERT C MSC17-C, CWE-484); the Linux kernel's 2019 audit for -Wimplicit-fallthrough found and fixed a number of them

How to fix it

Replace loop + break with stream pipelines using 'head' to take first N items, or use guards to process optional results.

See also

  • E01070: 'break' not supported (use stream pipelines with 'head')
  • E01071: 'continue' not supported (use stream pipelines with 'filter')
  • E01072: 'return' not supported (use return declarations)
  • E01073: 'null' not supported (use tri-state semantics)
  • E01074: semicolons not needed (indentation-based syntax)

https://ek9.io/streamsAndPipelines.html https://ek9.io/forAI.json#$.excludedFeatures.features[?(@.keyword=="break")]

Examples

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

Fails with E01070: 'break' does not exist in EK9 - use stream pipelines with 'head' or guards

#!ek9
defines module error.e01070.bad

  defines function

    firstLongWord()
      -> words as List of String
      <- found as String: String()
      longWordLength <- 5
      for word in words
        if length word > longWordLength
          found: word
          break

Fixed: Keep the first match with :=? (assign only while unset) instead of breaking out

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

  defines function

    firstLongWord()
      -> words as List of String
      <- found as String: String()
      longWordLength <- 5
      for word in words
        if length word > longWordLength
          found :=? word

Fixed: Stop pulling items with head instead of breaking out

#!ek9
defines module error.e01070.good

  defines function

    isLong() as pure
      -> word as String
      <- long as Boolean?
      longWordLength <- 5
      long: length word > longWordLength

    firstLongWord()
      -> words as List of String
      <- found as List of String: List()
      cat words | filter by isLong | head 1 > found

Fixed: Put the stopping condition in the loop condition

#!ek9
defines module error.e01070.good.while

  defines function

    countUntilLimit()
      -> limit as Integer
      <- counter as Integer: 0
      while counter < limit
        counter++

Questions and answers

These Q&A entries show E01070 and its fix: