How do I chain multiple if/else-if conditions?

← Control Flow · Ref: Q62

EK9 uses 'else if' as two separate words for chaining conditions. There is no 'elif' keyword (Python) or 'elsif' (Ruby/Perl). This is a deliberate choice for readability and consistency.

BASIC CHAIN

Conditions are evaluated top to bottom. The first matching branch executes:

  if score >= 90
    grade: "A"
  else if score >= 80
    grade: "B"
  else if score >= 70
    grade: "C"
  else if score >= 60
    grade: "D"
  else
    grade: "F"

Only one branch ever executes. Once a condition matches, the remaining branches are skipped.

COMPOUND CONDITIONS IN CHAINS

Each branch can use compound Boolean expressions:

  if age < 13
    category: "child"
  else if age < 18
    category: "teenager"
  else if age < 65 and isEmployed
    category: "working adult"
  else if age >= 65
    category: "retired"
  else
    category: "adult"

NO ELIF KEYWORD

Some developers coming from Python expect 'elif'. EK9 does not have this keyword. Using 'elif' will produce a compiler error. Always use 'else if' as two words.

WHEN TO USE SWITCH INSTEAD

If you are matching a single variable against specific values, consider switch instead of a long if/else-if chain:

  switch day
    case "Monday"
      action: "start of week"
    case "Friday"
      action: "end of week"
    default
      action: "mid week"

Switch is often clearer when testing one value against multiple possibilities. See Q63 for switch syntax. For comparison operators in switch cases (case < 12, case > 100), see Q70.

See Q61 for basic if/else syntax. See Q63 for switch as an alternative. See Q72 for 'when' as an alternative keyword.

Example

defines module qa.flow.chained.conditions

  defines function

    classifyAge() as pure
      -> ageInput as Integer
      <- rtn as Integer: ageInput

    checkEmployment() as pure
      -> employed as Boolean
      <- rtn as Boolean: employed

    classifyTemperature() as pure
      -> celsius as Float
      <- description as String: "unknown"

      lowTemp <- 10.0
      mildTemp <- 20.0
      warmTemp <- 30.0
      hotTemp <- 40.0

      if celsius < 0.0
        description: "freezing"
      else if celsius < lowTemp
        description: "cold"
      else if celsius < mildTemp
        description: "cool"
      else if celsius < warmTemp
        description: "warm"
      else if celsius < hotTemp
        description: "hot"
      else
        description: "extreme"

  defines program

    IfChainDemo()
      stdout <- Stdout()

      // === GRADE CLASSIFICATION ===

      scores <- [95, 82, 73, 61, 45]
      for score in scores
        grade <- String()
        excellent <- 90
        good <- 80
        average <- 70
        belowAverage <- 60
        if score >= excellent
          grade: "A"
        else if score >= good
          grade: "B"
        else if score >= average
          grade: "C"
        else if score >= belowAverage
          grade: "D"
        else
          grade: "F"
        stdout.println(`Score ${score} -> Grade ${grade}`)

      // === TEMPERATURE CLASSIFICATION (function) ===

      temperatures <- [Float(-5.0), Float(8.0), Float(15.0), Float(25.0), Float(38.0)]
      for temp in temperatures
        stdout.println(`${temp}C is ${classifyTemperature(temp)}`)

      // === COMPOUND CONDITIONS ===

      age <- classifyAge(30)
      isEmployed <- checkEmployment(true)
      category <- String()
      teenAge <- 13
      adultAge <- 18
      seniorAge <- 65
      if age < teenAge
        category: "child"
      else if age < adultAge
        category: "teenager"
      else if age < seniorAge and isEmployed
        category: "working adult"
      else if age >= seniorAge
        category: "retired"
      else
        category: "adult"
      stdout.println(`Age ${age}: ${category}`)

Common mistakes

E01072 — EK9 has no return statement. Assign to a pre-declared variable in each branch instead. The compiler verifies all paths initialise the variable. See ek9 -h E01072 for details.

Incorrect:

if score >= excellent
          return "A"

Correct:

if score >= excellent
          grade: "A"
        else if score >= good
          grade: "B"
Other ways to ask this
  • How does else-if work in EK9?
  • Why is there no elif in EK9?
  • How do I write multiple condition branches in EK9?

Coming from another language?

Java: else if with braces, no special keyword. Python: elif keyword (single word). Rust: else if with braces, if is an expression so match often preferred. Go: else if with braces, no special keyword. Ruby: elsif keyword. Perl: elsif keyword. Kotlin: else if, or 'when' expression for multi-branch. C#: else if with braces. JavaScript: else if with braces. Swift: else if with braces. EK9: else if (two words), no elif/elsif keyword, indentation-based blocks.

Keywords: if, multiple, flow, condition, else, chain, elif, branch, control, cascade, elsif, conditions, migrate