How do I provide a default value when something might be unset in EK9?
← Control Flow · Ref: Q985
EK9 provides two operators for default values:
?: COALESCE (ELVIS)
Returns the left value if SET, otherwise the right:
displayName <- userName ?: "Guest" timeout <- configuredTimeout ?: defaultTimeout
:=? ASSIGN-IF-UNSET
Only assigns if the target is currently UNSET:
serverHost <- String() serverHost :=? "localhost" serverHost :=? "other" has no effect — already set to localhost
WHEN TO USE EACH
?: when creating a new variable with a fallback.
:=? when conditionally initialising an existing variable.
COMBINING WITH GUARDS
if connection <- tryConnect(primaryHost) useConnection(connection) else fallbackHost <- primaryHost ?: backupHost if backup <- tryConnect(fallbackHost) useConnection(backup)
NOT ?? FOR DEFAULTS
?? (null coalescing) only tests whether the left operand is ABSENT. An unset value such as String() is present, so ?? passes it straight through and the result is still unset:
name <- String() name ?? "Guest" still unset name ?: "Guest" "Guest"
See Q1059 for the difference between ?? and ?:.
Example
defines module qa.controlflow.defaultvalue defines function lookupSetting() as pure -> settingName as String <- rtn as String: String() if settingName == "host" rtn: "production.example.com" defines program DefaultValueDemo() stdout <- Stdout() // ?: for inline defaults configuredHost <- lookupSetting("host") activeHost <- configuredHost ?: "localhost" stdout.println(`Host: ${activeHost}`) // ?: when lookup returns unset (?? would pass the unset value through) missingPort <- lookupSetting("port") activePort <- missingPort ?: "8080" stdout.println(`Port: ${activePort}`) // :=? for conditional initialisation logLevel <- String() logLevel :=? "INFO" stdout.println(`Log level: ${logLevel}`) // :=? has no effect when already set logLevel :=? "DEBUG" stdout.println(`Still: ${logLevel}`)
Other ways to ask this
- How do I fall back to a default in EK9?
- What is the EK9 equivalent of a default value expression?
- Does ?? or ?: give an unset value a default in EK9?
- How do I use :=? for conditional initialisation?
Coming from another language?
EK9 uses ?: (elvis) for an inline default and :=? for assign-if-unset. Both handle unset values without any concept of null. Unlike C#/Swift/JavaScript, EK9's ?? does NOT default an unset value - it only replaces an absent one.
Keywords: guarded, coalescing, fallback, default, unset