Nullish Coalesce & Guard
In Goblin, the ?? operator and its guarded form ?? => let you handle nix values cleanly and concisely.
Note
Nix is a special Goblin keyword that means "nil or empty". It covers both.
Nullish Coalesce (??)
What you write
x | maybe_value ?? fallback
x | maybe_value ?? fallback
What it does
If the left-hand value is not nix, it is used.
If it is nix, the fallback is used instead.
x | nil ?? 5 x /// -> 5
x | nil ?? 5 x /// -> 5
x | "hello" ?? "fallback" x /// -> "hello"
x | "hello" ?? "fallback" x /// -> "hello"
Nullish Guard (?? =>)
What you write
x | maybe_value ?? => action
x | maybe_value ?? => action
What it does
This form does not replace the value.
Instead, it:
- Tethers the value normally
- If the value is nix, runs the action
Equivalent to:
x | maybe_value if x.nix? => action
x | maybe_value if x.nix? => action
Example
x | nil ?? => :say("hit")
x | nil ?? => :say("hit")
Output:
hit x /// -> nil
hit x /// -> nil
Non-nix case
x | 1 ?? => :say("hit")
x | 1 ?? => :say("hit")
Output:
(no output) x /// -> 1
(no output) x /// -> 1
Works with Retether (|=)
x | nil x |= 1 ?? => :say("hit")
x | nil x |= 1 ?? => :say("hit")
Since 1 is not nix, nothing happens.
x /// -> 1
x /// -> 1
Inline Guard Actions
The right-hand side of => can be any single statement, including another inline if:
x | nil ?? => if true => :say("nested")
x | nil ?? => if true => :say("nested")
Output:
nested
nested
Early Return Pattern
The most common use of ?? => is returning early from an action when a value is nix:
act process(x)
body | x ?? => return ""
return body
xx
This replaces the two-line pattern:
body | x
if body.nix? => return ""
Formatting Notes
Inline form (preferred)
x | nil ?? => :say("hit")
x | nil ?? => :say("hit")
Tight form (also valid)
x | nil ??=> :say("hit")
x | nil ??=> :say("hit")
Multiline form (not supported)
x | nil ?? => :say("hit")
x | nil ?? => :say("hit")
This will currently produce a parse error.
How it differs
| Form | Behavior |
|---|---|
?? |
Replaces nix with a fallback value |
?? => |
Keeps the value, but runs an action if nix |
Why this exists
Goblin treats nil and empty values as a unified concept: nix.
These operators provide two clean patterns:
- Recover from nix →
?? - React to nix →
?? =>
This keeps logic compact without breaking the flow of tethering.