When does a switch need a returning block in EK9?

← Control Flow · Ref: Q782

EK9 switch can be used as a STATEMENT (no return) or as an EXPRESSION (returns a value). The compiler enforces consistency:

SWITCH AS STATEMENT

  switch category
    case "A"
      stdout.println("Category A")
    default
      stdout.println("Other")

No '<-' return block. The switch just executes side effects.

SWITCH AS EXPRESSION

  label <- switch category
    <- rtn as String: String()
    case "A"
      rtn: "Alpha"
    default
      rtn: "Unknown"

The '<- rtn as String' declares the return. Each case assigns to rtn.

RULES

- E07405: Using switch in assignment context WITHOUT a return block
- E07406: Adding a return block to a switch NOT in assignment context

THIS EXAMPLE

The classify() function uses switch as an expression with a correct return block. The showCategory program uses switch as a statement without a return block.

See Q63 for switch basics. See Q68 for switch as expression. See Q80 for loop expressions.

Example

defines module qa.controlflow.switchexpression

  defines function

    classify() as pure
      -> category as String
      <- label as String?

      label: switch category
        <- rtn as String: String()
        case "A"
          rtn: "Alpha"
        case "B"
          rtn: "Beta"
        default
          rtn: "Unknown"

  defines program

    ShowCategories()
      stdout <- Stdout()

      result <- classify("A")
      stdout.println(result)

      category <- "B"
      switch category
        case "A"
          stdout.println("Alpha")
        case "B"
          stdout.println("Beta")
        default
          stdout.println("Unknown")

Common mistakes

E07405 — A switch used in an assignment context ('label: switch ...') requires a returning block ('<- rtn as String'); without it the switch produces no value to assign. See ek9 -h E07405 for details.

Incorrect:

      label: switch category
        case "A"
          label: "Alpha"
        case "B"
          label: "Beta"
        default
          label: "Unknown"

Correct:

      label: switch category
        <- rtn as String: String()
        case "A"
          rtn: "Alpha"
        case "B"
          rtn: "Beta"
        default
          rtn: "Unknown"

E07406 — Adding a returning block to a switch that is not in an assignment context is pointless — the return value would be discarded. Remove the '<- rtn' declaration. See ek9 -h E07406 for details.

Incorrect:

      switch category
        <- rtn as String: String()
        case "A"
          stdout.println("Alpha")

Correct:

      switch category
        case "A"
          stdout.println("Alpha")
Other ways to ask this
  • What triggers E07405 returning required?
  • What triggers E07406 returning not required?
  • How do I use switch as an expression in EK9?

Coming from another language?

Java: switch expressions (Java 14+) use -> and yield. Python: match/case (3.10+) cannot return values directly. Rust: match is always an expression. Kotlin: when is always an expression. Go: switch is statement-only. EK9: switch can be either, compiler enforces correct form.

Keywords: E07406, E07405, assign, expression, switch, value, returning, block, statement