BoundCond (BoundCond v0.1.0)

Copy Markdown View Source

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
end

A :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

bound_cond(list)

(macro)

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}