What are given/when — alternative switch keywords?

← Control Flow · Ref: Q72

Yes. EK9 provides 'given' as a synonym for 'switch', and 'when' as a synonym for 'case'. They are semantically identical — the choice is purely stylistic.

BASIC GIVEN/WHEN

Use given/when instead of switch/case:

  given direction
    when "north"
      y: y + 1
    when "south"
      y: y - 1
    default
      stdout.println("Unhandled")

This is exactly equivalent to using switch/case.

ALL FOUR COMBINATIONS

You can mix the keywords freely:

  switch x + case:     switch value case 1 ...
  switch x + when:     switch value when 1 ...
  given x + case:      given value case 1 ...
  given x + when:      given value when 1 ...

All four are valid and behave identically.

EXPRESSION FORM

Given/when works in expression form:

  outcome <- given isReady
    <- rtn as String?
    when true
      rtn: "proceed"
    default
      rtn: "wait"

WITH ALL FEATURES

All switch features work with given/when:

  given temperature
    when < 0
      label: "freezing"
    when 20, 21, 22
      label: "comfortable"
    default
      label: "other"

Comparison operators, multiple values, pattern matching, guards, and exhaustive enum matching all work identically.

WHEN IN IF STATEMENTS

The 'when' keyword is also a synonym for 'if':

  when temperature < 0
    stdout.println("freezing")

See Q61 for if/when usage.

STYLE PREFERENCE

Some developers prefer given/when because it reads more naturally for certain types of logic, especially with Boolean conditions. Others prefer switch/case for familiarity. EK9 supports both to accommodate different preferences.

See Q63 for basic switch/case. See Q68 for switch/given as expression. See Q61 for if/when statements.

Example

defines module qa.flow.given.style

  defines function

    supplyStatusCode() as pure
      -> code as Integer
      <- rtn as Integer: code

    supplyReady() as pure
      -> ready as Boolean
      <- rtn as Boolean: ready

    supplyPriority() as pure
      -> level as Integer
      <- rtn as Integer: level

    supplyTemperature() as pure
      -> degrees as Integer
      <- rtn as Integer: degrees

    supplyDay() as pure
      -> day as String
      <- rtn as String: day

  defines program

    GivenWhenDemo()
      stdout <- Stdout()

      // === BASIC GIVEN/WHEN ===

      statusCode <- supplyStatusCode(200)
      statusMessage <- String()
      given statusCode
        when 200
          statusMessage: "OK"
        when 404
          statusMessage: "Not Found"
        when 500
          statusMessage: "Server Error"
        default
          statusMessage: "Unknown"
      stdout.println(`Status ${statusCode}: ${statusMessage}`)

      // === GIVEN/WHEN AS EXPRESSION ===

      isReady <- supplyReady(true)
      outcome <- given isReady
        <- rtn as String?
        when true
          rtn: "Proceed"
        default
          rtn: "Wait"
      stdout.println(`Ready: ${outcome}`)

      // === SWITCH WITH WHEN (MIXED) ===

      priority <- supplyPriority(1)
      urgency <- String()
      switch priority
        when 1
          urgency: "Critical"
        when 2
          urgency: "High"
        when 3
          urgency: "Medium"
        default
          urgency: "Low"
      stdout.println(`Priority ${priority}: ${urgency}`)

      // === GIVEN WITH COMPARISON OPERATORS ===

      temperature <- supplyTemperature(18)
      comfort <- String()
      given temperature
        when < 10
          comfort: "cold"
        when < 20
          comfort: "cool"
        when < 30
          comfort: "warm"
        default
          comfort: "hot"
      stdout.println(`${temperature}C is ${comfort}`)

      // === GIVEN/WHEN WITH MULTIPLE VALUES ===

      dayOfWeek <- supplyDay("Wednesday")
      scheduleType <- String()
      given dayOfWeek
        when "Monday", "Wednesday", "Friday"
          scheduleType: "gym day"
        when "Tuesday", "Thursday"
          scheduleType: "rest day"
        when "Saturday", "Sunday"
          scheduleType: "weekend"
        default
          scheduleType: "unknown"
      stdout.println(`${dayOfWeek} is ${scheduleType}`)

Common mistakes

E01070 — EK9 has no break statement. The given/when construct (synonym for switch/case) has no fallthrough, so break is unnecessary and nonexistent. See ek9 -h E01070 for details.

Incorrect:

given statusCode
        when 200
          statusMessage: "OK"
          break

Correct:

given statusCode
        when 200
          statusMessage: "OK"

E01072 — EK9 has no return statement. Given/when expressions use a declared return variable that is assigned in each branch. See ek9 -h E01072 for details.

Incorrect:

given isReady
        when true
          return "Proceed"
        default
          return "Wait"

Correct:

outcome <- given isReady
        <- rtn as String?
        when true
          rtn: "Proceed"
        default
          rtn: "Wait"
Other ways to ask this
  • Can I use given instead of switch in EK9?
  • What is the difference between switch/case and given/when?
  • Are given and when just synonyms for switch and case?

Coming from another language?

Kotlin: uses 'when' as its switch equivalent (not 'switch' keyword), very similar to EK9's given/when. Ruby: uses 'case/when' syntax, similar to EK9's alternative. Python: uses 'match/case' since 3.10. Rust: uses 'match' keyword. Go: uses 'switch/case'. Java: uses 'switch/case'. C/C++: uses 'switch/case'. JavaScript: uses 'switch/case'. Swift: uses 'switch/case'. EK9: provides both switch/case and given/when as interchangeable synonyms, plus 'when' as synonym for 'if'.

Keywords: style, keyword, preference, switch, condition, case, flow, branch, alternative, when, control, synonym, given