How do I try multiple configuration sources and use the first one that has a value?

← Control Flow · Ref: Q1038

Use :=? (guarded assignment) to try sources in priority order. Each :=? only evaluates its right side if the variable is still unset.

  setting <- String()
  setting :=? loadFromEnvironment()
  setting :=? loadFromConfigFile()
  setting :=? loadFromDefaults()

This tries environment first. If it returns a set value, the variable is assigned and the remaining calls are skipped. If not, it tries the config file, then defaults.

Why :=? instead of :=

  With :=, every source would be called and the last one always wins.
  With :=?, the first source that provides a value wins. Later sources are not evaluated.

This pattern replaces:

  if setting is not set then try next source

without any explicit checking. The operator handles it.

Use :=? when:

  - You want first-wins priority ordering
  - Later sources are expensive to evaluate
  - You want to preserve an existing value if present

Example

defines module qa.controlflow.guardedassign.configdefaults

  defines function

    loadFromEnvironment()
      <- rtn as String: String()
      //Simulate: environment variable not set

    loadFromConfigFile()
      <- rtn as String: "from-config"

    loadFromDefaults()
      <- rtn as String: "default-value"

  defines program

    ConfigDefaultsDemo()
      stdout <- Stdout()

      //Priority chain: environment -> config file -> defaults
      setting <- String()
      setting :=? loadFromEnvironment()
      setting :=? loadFromConfigFile()
      setting :=? loadFromDefaults()

      stdout.println(`Setting resolved to: ${setting}`)

      //Second example: already has a value, so :=? skips
      name <- loadFromEnvironment()
      name :=? loadFromDefaults()
      stdout.println(`Name preserved: ${name}`)

Common mistakes

E01073 — 'null' does not exist in EK9. Use ':=?' to conditionally assign — it only evaluates and assigns when the variable is currently unset.

Incorrect:

      if setting == null
        setting := loadFromConfigFile()

Correct:

      setting :=? loadFromConfigFile()
Other ways to ask this
  • What is the EK9 pattern for fallback configuration?
  • How does :=? work for default value chains?
  • Show me priority-ordered assignment in EK9

Coming from another language?

Java needs explicit null checks for each source. Python uses 'x = x or next_source()' but fails with falsy values. EK9's :=? handles it correctly in one operator.

Keywords: config, priority, assign, fallback, default, guarded