How do I guard a date lookup so the block only runs if a date is found?

← Control Flow · Ref: Q1196

EK9 guard variables combine declaration with an isSet check. If the function returns an unset Date, the if body is skipped.

GUARD PATTERN

  if deadline <- findDeadline()
    stdout.println(deadline)      only runs if deadline is set
  else
    stdout.println("No deadline")  runs if deadline is unset

The guard works identically for Date, Time, Money, String, or any type with the ? operator. One universal pattern replaces null checks across all types.

FUNCTION RETURNING UNSET

  findDeadline()
    <- rtn <- Date()    Date() creates an unset Date

See Q74 for guard if. See Q75 for guard switch. See Q76 for guard for. See Q77 for guard while.

Example

defines module qa.flow.guard.withdate

  defines function

    findDeadline()
      <- rtn <- Date()

    findActiveDeadline()
      <- rtn <- 2024-09-30

    findProjectEnd()
      <- rtn <- 2024-12-31

  defines program

    GuardWithDateDemo()
      stdout <- Stdout()

      // === GUARD WITH UNSET DATE ===

      if deadline <- findDeadline()
        stdout.println(`Deadline: ${deadline}`)
      else
        stdout.println("No deadline found")

      // === GUARD WITH SET DATE ===

      if deadline <- findActiveDeadline()
        stdout.println(`Active deadline: ${deadline}`)
      else
        stdout.println("No active deadline")

      // === GUARD WITH ADDITIONAL CONDITION ===

      today <- 2024-06-15
      if projectEnd <- findProjectEnd() with projectEnd > today
        stdout.println(`Project ends in the future: ${projectEnd}`)

      // === GUARD SCOPING ===
      // The guard variable is scoped to the if/else block
      // It does not leak into surrounding scope

      if dueDate <- findActiveDeadline()
        daysMessage <- `Due: ${dueDate}`
        stdout.println(daysMessage)

      // === MULTIPLE GUARDS IN SEQUENCE ===

      if first <- findActiveDeadline()
        if second <- findProjectEnd()
          if first < second
            stdout.println(`Active deadline is before project end`)

Common mistakes

E01072 — EK9 has no null and no return statement. Use guard variables in if statements to combine declaration and isSet checking in one expression. See ek9 -h E01072 for details.

Incorrect:

deadline <- findDeadline()
      if deadline == null
        return
      stdout.println(deadline)

Correct:

      if deadline <- findDeadline()
        stdout.println(`Deadline: ${deadline}`)
      else
        stdout.println("No deadline found")
Other ways to ask this
  • Use an if guard with a Date return value in EK9.
  • I need to safely handle a function that might not return a valid deadline.
  • In Java I checked if the date was null — how does EK9 guard against unset dates?

Coming from another language?

Java: if (date != null) { use(date); } — null check separate from declaration. Python: if date := get_date() (walrus, 3.8+, None only). Rust: if let Some(d) = find_deadline(). Go: if d := findDeadline(); d != nil. Kotlin: val d = findDeadline(); if (d != null). EK9: if deadline <- findDeadline() — one expression for declare + check + scope.

Keywords: flow, temporal, deadline, safe, lookup, check, date, unset, guard, if, control