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

#!ek9
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?
        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: check, control, date, deadline, flow, guard, if, lookup, safe, temporal, unset