Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Railway Oriented Programming macros in Elixir
defmodule ROP do
defmacro try_catch(args, func) do
quote do
(fn ->
try do
unquote(args) |> unquote(func)
rescue
e -> {:error, e}
end
end).()
end
end
defmacro tee(args, func) do
quote do
(fn ->
unquote(args) |> unquote(func)
{:ok, unquote(args)}
end).()
end
end
defmacro bind(args, func) do
quote do
(fn ->
result = unquote(args) |> unquote(func)
{:ok, result}
end).()
end
end
defmacro left >>> right do
quote do
(fn ->
case unquote(left) do
{:ok, x} -> x |> unquote(right)
{:error, _} = expr -> expr
end
end).()
end
end
end

You unquote args twice in the tee macro. I know elixir is immutable but I wonder if it can cause troubles later because the code is executing twice.

Yes, it will cause the code to execute twice. Try that by sneaking in a side effect causing statement in args. A better method is to use

defmacro tee(args, func) do
  quote bind_quoted: [args: args, func: func] do
    (fn ->
      args |> func
      {:ok, args}
    end).()
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment