How does EK9 ensure variables are used only after they are defined?

← Data Flow Safety · Ref: Q632

EK9 enforces sequential definition order within a scope. A variable must be declared before any reference to it. This prevents an entire category of bugs where code accidentally references a variable that does not yet exist.

DEFINITION ORDER RULE

Within a function, method, or program body, statements execute top-to-bottom. A variable declared on line 10 cannot be referenced on line 8. The compiler checks this and raises E08010 if the reference precedes the declaration.

WHY THIS MATTERS

Forward references to variables are a common copy-paste error. A developer moves a block of code above its variable declarations and the program silently reads uninitialized memory (in C) or gets undefined (in JavaScript). EK9 eliminates this by making definition order a compile-time guarantee.

EXCEPTIONS

Types and functions can be forward-referenced because EK9 resolves them in a separate phase. Only local variables, parameters, and fields follow strict sequential order.

CORRECT PATTERN

Declare each variable before using it. Group related declarations near their first use. The compiler verifies every reference has a preceding declaration in the same or enclosing scope.

See Q633 for initialization tracking across branches. See Q251 for debugging unset variable errors.
See Q688 for variable init order. See Q692 for field initialization.

Example

defines module qa.dataflow.definitionorder

  defines function

    <?-
      Correct: each variable is declared before it is used.
      taxRate is declared before taxAmount references it.
    -?>
    computeTotal() as pure
      -> basePrice as Float
      <- total as Float: basePrice

      taxRate <- 0.15
      taxAmount <- basePrice * taxRate
      total: basePrice + taxAmount

    <?-
      Correct: intermediate results are computed in order.
      Each step uses only previously declared variables.
    -?>
    computeDiscount() as pure
      ->
        originalPrice as Float
        discountPercent as Float
      <- finalPrice as Float: originalPrice

      discountFraction <- discountPercent / 100.0
      discountAmount <- originalPrice * discountFraction
      finalPrice: originalPrice - discountAmount

    <?-
      Correct: variables defined in sequence, each referencing
      only previously declared values.
    -?>
    buildGreeting() as pure
      ->
        firstName as String
        lastName as String
      <- greeting as String: firstName

      fullName <- `${firstName} ${lastName}`
      greeting: `Hello ${fullName}, welcome`

  defines program

    DefineBeforeUseDemo()
      stdout <- Stdout()

      totalPrice <- computeTotal(100.0)
      stdout.println(`Total: ${totalPrice}`)

      discounted <- computeDiscount(200.0, 15.0)
      stdout.println(`Discounted: ${discounted}`)

      msg <- buildGreeting("Alice", "Smith")
      stdout.println(msg)

Common mistakes

E08010 — Referencing taxRate before it is declared is a forward reference error. Variables must be declared before use. See ek9 -h E08010 for details.

Incorrect:

taxAmount <- basePrice * taxRate
      taxRate <- 0.15

Correct:

taxRate <- 0.15
      taxAmount <- basePrice * taxRate

E50001 — Removing the variable declaration means later references to the variable become unresolved, triggering E50001. See ek9 -h E50001 for details.

Incorrect:

computeTotal(100.0)

Correct:

totalPrice <- computeTotal(100.0)
Other ways to ask this
  • What happens if I use a variable before declaring it?
  • Does EK9 check declaration order?
  • What is E08010 used before defined?

Coming from another language?

Java: variables must be declared before use (compiler error). JavaScript: var hoisting allows use before declaration (reads as undefined). Python: NameError at runtime if variable not yet assigned. C: undefined behavior if variable not initialized. Go: compile error for undeclared variable. Rust: compile error for uninitialized variable. EK9: compile error E08010 for any reference before declaration, enforced at Phase 3.

Keywords: define, scope, before, forward, order, E08010, safety, initialize, migrate, reference, data-flow, declaration, use, variable