What does the ? operator mean in EK9?

← Operators and Expressions · Ref: Q898

In EK9, the ? operator checks if a value is SET. It is a SUFFIX operator — append it after the variable name.

WHAT ? DOES

The ? operator goes AFTER the variable:

  name <- String()       declared but UNSET
  if name?               false — name has no value yet
    stdout.println(name) skipped
  name := "Alice"        now SET
  if name?               true — name has a value
    stdout.println(name) prints "Alice"

The ? operator calls _isSet() internally and returns Boolean.

TRI-STATE MODEL

EK9 objects have three states:
1. ABSENT — object doesn't exist (Optional empty, Dict missing key)
2. PRESENT but UNSET — object exists but has no meaningful value
3. PRESENT and SET — object exists with valid, usable value

The ? operator checks for state 3 (set with meaningful value).

USE IN CONDITIONS

  if userName?                    single check
  if firstName? and lastName?     compound check
  isReady <- connection?          assign Boolean result

COLLECTION SEMANTICS

Collections (List, Dict) are ALWAYS set when created, even if empty:

  emptyList <- List() of Integer
  emptyList?              trueempty list IS set

See Q24 for tri-state semantics. See Q981 for more ? examples.

Example

defines module qa.operators.issetnotternary

  defines function

    <?-
      Shows ? operator checking if value is SET.
      Like Rust: Option.is_some()
      NOT like JavaScript: condition ? a : b
    -?>
    describeState() as pure
      -> userName as String
      <- rtn as String: String()

      // ? checks if userName is SET (has meaningful value)
      if userName?
        rtn := `User: ${userName}`
      else
        rtn := "No user set"

    <?-
      Shows guard expression as alternative to ternary.
      EK9 has no ternary — use :=? instead.
    -?>
    getDisplayName() as pure
      ->
        firstName as String
        fallbackName as String
      <-
        displayName as String: String()

      // :=? only assigns if displayName is currently UNSET
      displayName :=? firstName
      displayName :=? fallbackName
      displayName :=? "Anonymous"

  defines program

    IsSetDemo()
      stdout <- Stdout()

      // ? operator — like Rust's is_some()
      emptyName <- String()
      stdout.println(describeState(emptyName))

      filledName <- "Steve"
      stdout.println(describeState(filledName))

      // Collections are ALWAYS set when created
      // Note: List() is always set, so no need for isSet check
      emptyNumbers <- List() of Integer
      emptyCount <- length emptyNumbers
      stdout.println(`Empty list has ${emptyCount} items (but IS set)`)

      // Guard expression instead of ternary
      displayA <- getDisplayName("Alice", "Default")
      stdout.println(`Display: ${displayA}`)

      displayB <- getDisplayName(String(), "Fallback")
      stdout.println(`Display: ${displayB}`)

Common mistakes

E01073 — 'null' does not exist in EK9. Append ? after the variable to check if it is set: 'if userName?' See ek9 -h E01073.

Incorrect:

      if userName != null
        stdout.println(userName)

Correct:

      if userName?
        rtn := `User: ${userName}`
Other ways to ask this
  • How does isSet work in EK9?
  • What does the question mark operator do in EK9?
  • How do I check if a variable is set in EK9?
  • What does appending ? after a variable do in EK9?

Coming from another language?

EK9's suffix ? checks if a value is set — append it after any variable name. Returns Boolean, no parentheses needed.

Keywords: unset, suffix, check, tri-state, set, isSet, Rust, Option, operator, question