Crowdhailer
Creator of Raxx
This example overrides Kernel.def/2, so I am aware it is only suitable as an experiment. However here are the results.
Given the functions fetch_user and fetch_cart that both return {:ok, value} or {:error, reason}.
defmodule MyApp do
use OK.Kernel
def checkout(user_id, cart_id) do
user <- fetch_user(user_id) # `<-` will bind user when fetch_user returns {:ok, user}
cart <- fetch_cart(cart_id) # `<-` will shortcut to else clause if returned {:error, reason}
order = checkout(cart, user) # Lines without `<-` behave normally
order.invoice_id
else
:user_not_found ->
IO.puts("No user for user_id: #{user_id}")
nil
:cart_not_found ->
IO.puts("User has no cart")
nil
end
end
By using OK.Kernel errors can be grouped in what I consider to be a very natural way.
I guess it’s natural because it looks like how I would arrange raise and catch in previous languages. However with the magic of Elixir macros I can do it all without using exception raising.
To try it yourself add the release candidate to your mix.exs
{:ok, "~> 1.7.0-rc.1"}
Comments welcome.
My motivation for trying this was to separate unhappy paths due to code errors ( I still raise exceptions for them) and the unhappy path due to bad input.
Trending in Announcing
WebAuthnLiveComponent WebAuthnComponents
See this post about renaming the package.
Passwordless authentication for Phoenix LiveView app...
New
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I released Doggo, a collection of unstyled Phoenix components.
https://github.com/woylie/doggo
Features
Unstyled Phoenix components....
New
Hi everyone,
I’ve been working on this protobuf library for 3 years. We use it in the company I work for, EasyMile, to communicate with ...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
I’ll shortly be launching Text, a nascent text analysis library.
Current functionality
In this early version (not ready for prime time) ...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with.
But I don’t use it anymore.
Serverless was the promis...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex










Showing Posts 1 to 7- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Eiji
@Crowdhailer:
:user_not_foundin example codeelseto something … elseHow about:
catch_error?<-to for example:<=defanddefpand addedefandedefpwhere: e <= extendedImagine:
Compare it to:
What do you think about it?
aseigo
Personally, I think this leads to hard to reason about code due to the loss of locality between the function body and the else that may or may not be triggered. It’s the same reason goto is “considered harmful” (caveats and exceptions to that aside
)
This feels like a place where
withwould be a good solution. A bit of syntatic sugar around it to tease the behavior of with to automatically succeed on {:ok, anything} and fail on {:error, anything} would be nicer imho, and iirc someone recently did exactly that.Also, I find that if I have long(er) functions where there are conditions somewhere in the middle that need to branch, such as on failure or success, that this is a signal that perhaps I should break that function there and send processing on to another function which will continue on success or return on failure.
IOW, each function goes as far as it can until need to react to a success/failure and at that point calls another function. So each function ends up being a bit-sized bit of code that does execute completely, allowing each function to be reasoned about simply and clearly.
Exceptions (or, what they really are: early returns) are a tool of “last resort” for me, used when they are really required only. Similarly for case/with/etc. If those start nesting, or a function ends up being a series of them, I take that as a code smell to start chopping that function up into more atomic sets of code to stuff into functions.
Crowdhailer
Thanks for the typo spot. have edited it.
I have to use else, only certain terms will split up a do block in the ast, i think I could use
catchorrescuebut that is the end of the choices.maybe? why?
If you don’t like overriding the
OKlibrary has other options including its own version of with.@aseigo I think you are probably refering to other features in the
OKlibrary for the alternative to withaseigo
Indeed it is .. small worlds
Eiji
@Crowdhailer:
2. oh, I see … How about store method name in atom instead of code block?
Is it (or something similar possible?
2. and 3. because new Elixir developer could be confused when see that some operators do multiple works
I added it in example codes. Compare
for item <- items ...withitem <- get_items()and that part whenifis directly aboveelse- as a … not new developer I don’t have a problem with it, but I can see that it could be confused for new users.4. yes, I saw that - btw. good job
Crowdhailer
The
<-is deliberately the same, because considering things as a monad it is the same operation (a bind).This is very pseudocode but eventually you could have something like.
aseigo
Oooh… catch_with would be rather nice imho .. great idea! Now .. is it possible?
If it is .. +1 from my (largely irrelevant) vote