coming from erlang elixir is much nicer than that. exunit is miles ahead of eunit and i feel like that would be enough to convince me to switch.<p>the with syntax is nice and helps to deal with early exit on errors but still feels a bit awkward compared to imperative control flow.<p>like you can do something like this in an imperative language:<p><pre><code> foo, err = func()
if err != nil {
return nil, Err("bad")
}
bah, err = func2(foo)
if err != nil {
return nil, Err("blah")
}
return bah
</code></pre>
whereas in elixir you have to do something like the following in order to avoid the nesting of doom:<p><pre><code> with {ok, foo} <- func() |> Error.or({:error, "bad"}),
{ok, bah} <- func2(foo) |> Error.or({:error, "blah"}), do
bah
end
</code></pre>
like the with blocks kind of work until you have to transform the errors you receive then you need helper functions. if you are just doing static transforms like above it is not too bad but it starts to get hairy if you want to transform based on the returned error or variables in the function. whereas the imperative style you can inline your error handling logic nicely into the function.<p>for example what if i want to log something on the error path that includes some contextual information and custom formatting. probably, the easiest way is going to be to use with() and pipe to a custom function that triggers on the error path to do the logging because the code is going to start getting really messy. whereas if i was writing it imperatively i could just inline the logging statement most of the time because it is just a few lines of code.<p><pre><code> foo, err = func()
if err != nil {
return nil, Err("bad")
}
bah, err = func2(foo)
if err != nil {
Logger.error("err: " + err + " when processing: " + foo.name)
return nil, Err("blah")
}
return bah
</code></pre>
like i feel this is a bit messy but maybe it is actually not that bad:<p><pre><code> with {ok, foo} <- func() |> Error.or({:error, "bad"}),
{ok, bah} <- func2(foo) |> Error.or_else(fn err ->
Logger.error("err: " <> err <> " when processing: " <> foo.name)
{:error, "blah"}
end), do
bah
end</code></pre>