bound_cond/1 — a cond whose clauses can thread interim variables.
Plain cond runs the first truthy clause's body, but each clause is isolated:
a value computed while testing one condition can't be reused by the next.
with can thread state, but it models a single happy path with fallbacks —
not several branches of equal priority. bound_cond/1 fills that gap.
Clauses are tried top to bottom, exactly like cond. To introduce variables
for the clauses that follow, add a :bind -> step:
import BoundCond
bound_cond do
in_range?( x, y) ->
n
:bind ->
last = get_last( x)
pos = get_pos( y)
pos > last ->
last
true ->
pos
endA :bind -> clause never "matches": its body runs only when execution falls
through to it, and the variables it binds stay in scope for every clause below
it — but, like cond, nothing bound inside a bound_cond leaks out of it
(not even an unconditional :bind). If no clause matches, a CondClauseError
is raised, just like cond.
It expands to nested if/else wrapped in a case (used only to open a
scope, so the bindings can't leak), so there is effectively no runtime
overhead.
Summary
Functions
A cond whose clauses can share interim variables.
Functions
A cond whose clauses can share interim variables.
Use one or more :bind -> ... steps to bind variables for the clauses that
follow them.
Examples
iex> import BoundCond
BoundCond
iex> x = 7
7
iex> bound_cond do
...> x < 0 ->
...> :negative
...>
...> :bind ->
...> doubled = x * 2
...>
...> doubled > 10 ->
...> { :big, doubled}
...>
...> true ->
...> { :small, doubled}
...> end
{:big, 14}