Trace the execution flow through these guard expressions. What values get printed?

← Control Flow · Ref: Q991

Tracing the execution:

1. fetchTemperature("London") returns 18.5 (set). Guard succeeds.

   Prints: 'London: 18.5C'

2. fetchTemperature("Atlantis") returns unset (unknown city). Guard fails.

   The if block is skipped. The else block runs.
   Prints: 'Atlantis: no reading available'

3. fetchTemperature("Dubai") returns 42.0 (set). Guard succeeds AND 42.0 > heatThreshold (35.0).

   The then condition passes.
   Prints: 'Dubai heat warning: 42.0C'

4. fetchTemperature("Oslo") returns 3.0 (set). Guard succeeds BUT 3.0 is NOT > heatThreshold.

   The then condition fails. The entire if block is skipped.
   No output for Oslo.

Guards combine declaration + isSet check in one step. The 'then' clause adds an additional condition that must also be true.

Example

defines module qa.controlflow.explainguardflow

  defines function

    fetchTemperature() as pure
      -> cityName as String
      <- rtn as Float: Float()

      londonName <- "London"
      dubaiName <- "Dubai"
      osloName <- "Oslo"

      if cityName == londonName
        rtn: 18.5
      else if cityName == dubaiName
        rtn: 42.0
      else if cityName == osloName
        rtn: 3.0

  defines program

    GuardFlowDemo()
      stdout <- Stdout()

      heatThreshold <- 35.0

      //Guard succeeds — London returns a set value
      if londonTemp <- fetchTemperature("London")
        stdout.println(`London: ${londonTemp}C`)

      //Guard fails — Atlantis returns unset
      if atlantisTemp <- fetchTemperature("Atlantis")
        stdout.println(`Atlantis: ${atlantisTemp}C`)
      else
        stdout.println("Atlantis: no reading available")

      //Guard with then — Dubai is set AND above threshold
      if dubaiTemp <- fetchTemperature("Dubai") then dubaiTemp > heatThreshold
        stdout.println(`Dubai heat warning: ${dubaiTemp}C`)

      //Guard with then — Oslo is set but NOT above threshold
      if osloTemp <- fetchTemperature("Oslo") then osloTemp > heatThreshold
        stdout.println(`Oslo heat warning: ${osloTemp}C`)

Common mistakes

E01073 — 'null' does not exist in EK9. Use the guard pattern 'if v <- expr()' to combine declaration with isSet checking. See ek9 -h E01073.

Incorrect:

      londonTemp <- fetchTemperature("London")
      if londonTemp != null
        stdout.println(`London: ${$londonTemp}C`)

Correct:

      if londonTemp <- fetchTemperature("London")
        stdout.println(`London: ${londonTemp}C`)
Other ways to ask this
  • Walk through this EK9 code and predict the output
  • What does each guard expression do in this code?
  • Explain the control flow when guards encounter unset values

Coming from another language?

EK9 guards replace null checks from other languages. The if v <- expr() pattern declares, checks isSet, and optionally tests a condition in one atomic step.

Keywords: trace, flow, output, predict, guard, execution