I wanted to share this code for a problem that regularly comes up and that I usually solve with multi-headed functions or with clauses. The issue: handling an error tuple in a pipeline situation by skipping steps.
Here’s the code: (Important: There’s a bug in this macro, see below)
defmacro left ~> right do
quote do
case unquote( left ) do
{ :error, _ } = err -> err
val -> unquote( Macro.pipe( left, right, 0 ) )
end
end
end
Which makes possible a pipeline that looks like:
start_value
|> step_a
~> step_b
~> step_c
|> step that handles { :error, _ } or a real result
That’s pretty common, what what the exceptional library on hex.pm does (it handles raw values, tagged ok/error tuples, returning exceptions, multiple styles of handling errors, etc…). I use it quite a lot.
This is the Kernel.|>/2 macro sequence. It felt a little unsatisfying knowing it translates into Macro.pipe. With a little more time and testing it seems to cleanly reduce to:
The code printing comes from an inline Macro.to_string( ast ) for illustration. The code shows backward since the unpipe rolls the pipe up in reverse while nesting.