E01072: 'return' does not exist in EK9 - declare return values with '<-' and compiler ensures all paths initialize

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

What went wrong

The 'return' statement does not exist in EK9.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 49 (How do I define a function in EK9?)
  • ek9 -q 61 (How do if/else statements work in EK9?)
  • ek9 -q 62 (How do I chain multiple if/else-if conditions?)
  • ek9 -q 63 (How does switch/case work in EK9?)
  • ek9 -q 19 (Can I use EK9 for scripting?)

Rationale

EK9 excludes early returns based on critical security evidence:

  • Apple SSL Bug (2014, CVE-2014-1266): Duplicate 'goto fail' bypassed SSL validation
  • An early exit between acquiring a resource and releasing it skips the release
  • Multiple return points make code harder to reason about

How to fix it

Declare return variable with '<-' and let compiler enforce all paths initialize it. Use guards for conditional processing.

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/flowControl.html#guard_decision_tree https://ek9.io/forAI.json#$.excludedFeatures.features[?(@.keyword=="return")]

Examples

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

Fails with E01072: 'return' does not exist in EK9 - declare return values with '<-' and compiler ensures all paths initialize

#!ek9
defines module error.e01072.bad

  defines constant
    LIMIT <- 100

  defines function

    //Return with a value
    tryReturnWithValue()
      -> text as String
      <- result as String: String()
      return text

    //Return without a value (void return)
    tryReturnWithoutValue()
      -> message as String
      if message?
        Stdout().println(message)
        return

    //Early return in conditional
    tryEarlyReturn()
      -> name as String
      <- result as String: String()

      if not name?
        return "anonymous"

    //Return inside a for loop
    tryReturnInForLoop()
      -> items as List of Integer
      <- result as Integer: Integer()

      for item in items
        if item > LIMIT
          return item

    //Return inside a while loop
    tryReturnInWhileLoop()
      -> items as List of Integer
      <- result as Integer: Integer()

      iter <- items.iterator()
      while iter.hasNext()
        item <- iter.next()
        if item > LIMIT
          return item

Fixed: Assign the returning variable where each return was

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

  defines constant
    LIMIT <- 100

  defines function

    //Return with a value
    tryReturnWithValue()
      -> text as String
      <- result as String: String()
      result: text

    //Return without a value (void return)
    tryReturnWithoutValue()
      -> message as String
      if message?
        Stdout().println(message)

    //Early return in conditional
    tryEarlyReturn()
      -> name as String
      <- result as String: String()

      if not name?
        result: "anonymous"

    //Return inside a for loop
    tryReturnInForLoop()
      -> items as List of Integer
      <- result as Integer: Integer()

      for item in items
        if item > LIMIT
          result :=? item

    //Return inside a while loop
    tryReturnInWhileLoop()
      -> items as List of Integer
      <- result as Integer: Integer()

      iter <- items.iterator()
      while iter.hasNext()
        item <- iter.next()
        if item > LIMIT
          result :=? item

Fixed: Declare the returning variable and assign it; the compiler checks every path

#!ek9
defines module error.e01072.good

  defines function

    describe()
      -> name as String
      <- description as String: "anonymous"
      if name?
        description: "named " + name

    firstOver()
      ->
        items as List of Integer
        threshold as Integer
      <- found as Integer: Integer()
      for item in items
        if item > threshold
          found :=? item

Questions and answers

These Q&A entries show E01072 and its fix: