giddie
Ok_then - The Swiss Army Knife for tagged tuple pipelines
GitHub: GitHub - flexibility-org/ok_then: The Swiss Army Knife for tagged tuple pipelines · GitHub
HexDocs: OK then... — ok_then v1.1.0
I just couldn’t quite find what I was looking for when it came to handling tagged tuples. In particular, I really wanted to find an elegant solution to the problem of missing return values that are not errors. Because sometimes, a missing return value is an error, and other times it’s not. Rust handles this very elegantly, using separate Result (Ok / Error) and Option (Some / None) types, often in tandem.
So I decided I had to write my own solution for handling tagged tuples. And I’m quite pleased with the result. Of course I have to give credit to those who have gone before, such as the authors of the “OK” and “Croma” packages.
The most controversial feature will be the addition of :none alongside :ok and :error, though this becomes mostly transparent in pipelines.
There are a few more functions I’d like to add, in particular to the Result.Enum module. And I’d also like a monadic “with”-like macro, similar to that offered by the “OK” package.
Most Liked
dimitarvp
What does a new convention of :ok / :none achieve that hasn’t been achieved by the :ok / :error convention?
If a function does not return data then it can just return :ok (not a tuple).
When you say semantics and consistency, I am not seeing it. It’s OK to have a personal preference but I don’t see the value.
As for nil, well, I think we all know that’s a huge and very expensive mistake in computer science in general. But as others pointed out, nil is also an atom so replacing it with another one doesn’t help much. Not sure I am seeing the argument for the stack traces as well.
Maybe I just don’t get it though.
dorgan
There are some functions that return none, like erlang:dist_ctrl_get_data, erlang:system_info, but it seems in those cases it means “set to none” or “not available” rather than “not found”
giddie
Yes, absolutely. The ok_then library will also accept any bare atom (:some, :success, :ok, …). It interprets these internally as {:ok, {}}, {:some, {}}, ..., so mapping functions will receive {} as the wrapped value, and that’s what unwrap!() would return too. It’s just that :none is returned by Result.from/1 and Result.map/2 if they receive nil as a value to wrap, and there are shorthand functions to handle :none, such as default/2 and none_then/2.
So if you want, you could fall back to a bare :ok quite easily like this:
Result.from(nil) # :none
|> Result.default({}) # :ok
# or
Result.from(nil) # :none
|> Result.none_then(:ok) # :ok
As another Rust guy I can see where you’re coming from. But my view is that beyond avoiding
nilat all costs, the rest is kind of achievable with fairly vanilla Elixir. But I get the need: you want chainable / pipeable value, which is fair.
I’d be interested in some testcases, actually. Could I tempt you to come up with some examples of vanilla Elixir that we could compare to an equivalent using the ok_then library?
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
- #javascript
- #code-sync
- #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








