Crowdhailer
OK - elegant error handling with result monads (alternative to Elixir `with` special form)
Experimenting with this code.
OK.try do
user <- fetch_user(1)
cart <- fetch_cart(1)
order = checkout(cart, user)
save_order(order)
end
Ok.with/1 supports an else block that can be used for handling error values.
OK.with do
a <- safe_div(8, 2)
_ <- safe_div(a, 0)
else
:zero_division -> # matches on reason
{:ok, :inf} # must return a new success or failure
end
The cart example above is equivalent to
with {:ok, user} <- fetch_user(1),
{:ok, cart} <- fetch_cart(1),
order = checkout(cart, user),
{:ok, order_id} <- save_order(order)
do
{:ok, order_id}
end
I have an implementation marked as beta as part of my OK project.
The Elixir with keyword has been very helpful for handling code with lots of branches, normally many error conditions. Such as the example above.
In the with example I find it is strange that the majority of my code my code lives in a list of arguments. It starts to get very lumpy if there are receive blocks or anonymous functions to get these values. Also in 90% of cases I am matching on an :ok tuple so don’t want to repeat that.
For these reasons I have been using the alternative macro from OK. It is far more restrictive because it will only match on :ok/:error tuples. However I like the restriction because it means that no matter how complex the block it will also only return :ok/:error tuples.
I am not sure that try is the best name. Alternatives that I am considering are
- when, seams so make sense linguistically but already a keyword in elixir
- with, familiar to elixir users
- for, monadic for comprehension which is what this is but that might not be a very accessible term.
- try, As is, however it doesn’t catch errors so the name could be misleading
Most Liked
ibgib
I like OK.with because
- It let’s regular elixir users immediately grok that it’s like
with. - It’s idiomatic English! “I’m OK with that.”
(Try sounds like a try/catch/rescue replacement as opposed to a with replacement)
chrismccord
This is a great lib for playing with macros! That said, I’m personally
on efforts around alternatives to with, as I haven’t seen justified benefits.
It’s worth pointing out that you should call out to functions in those cases. Also where you are seeing repetition, I am seeing explicit matching. The issues with Ok is that is hides the true match, and it gets more confusing if you were include a match within the 2nd elem, i.e. %{key: val} <- .... Is the rhs returning a tuple or map? It also breaks down the moment you want to match on something not in an :ok tuple. Using with, you simply add a new clause, with Ok you need to rewrite the entire block.
Crowdhailer
Version 1.10.0: Add map/2 and ~> to treat result tuples as Functors.
The latest version of ok (1.10.0) has been release. It adds functionality to transform a value within an :ok tuple. e.g.
Examples
iex> {:ok, 5} ~> Integer.to_string
{:ok, "5"}
iex> {:error, :zero_division_error} ~> Integer.to_string
{:error, :zero_division_error}
iex> {:ok, "a,b"} ~> String.split(",")
{:ok, ["a", "b"]}
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









