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.