Isn't the way to deal with that problem is to hoist those clauses into functions with different pattern signatures and rely on function-head matching?
Everything else looks awesome. I have to say, somewhat selfishly, that my favorite part of Elixir is actually the pressure it's putting on the Erlang community to up its game and care more about developer experience and enablement through better tooling, etc.
I'm new to Elixir but I've definitely run into the "byzantine case-clause" issue and it can be very annoying. My case was very similar to the example: pulling something from a form, validating the format, validating it in the database, and returning something. All failable, single-purpose functions in sequence to narrow down the result.
I grappled between using a monad macro library[0] to simplify `{:ok, _}`/`{:error, _}` signatures versus just raising exceptions. I ended up doing the latter for the additional benefit of stack traces. Exceptions seem culturally discouraged in Elixir, though I don't quite grok why yet.
Out of curiosity, would you be willing to show how you might refactor the post's "create_organization" example?
The first one is that usually we do not want to rescue them, the let it crash philosophy. If an error happens, the the process will crash, it will be restarted, the error will be logged, and everyone will be happy.
In the case we really do want to handle an error, we can usually just use `case` or `with`, which are simpler, avoids to rescuing something we did not expect, as well as some pitfalls, for example the fact that recursive calls inside a `try` cannot be optimized to be tail-recursive, which can be an issue depending on the case.
However, I think it is fine to use exceptions if it can avoid deeply nested code, which was probably your case.
However, I'm not sure what you mean by "there are some cases where it makes sense to have multiple things that could failed grouped in the same function". I'm almost certainly misinterpreting what you're saying, but that sounds like setting up a situation where it's harder to know exactly what failed because you're grouping failure modes together, which now means you need to have more understanding/context of your application and the local execution environment surrounding the point of failure to reason about what actually happened.
Almost always, except cases where I can't usefully trap a somewhat questionable lower-level API, I only ever, ever program the "happy path" in Elixir and Erlang. If I find myself doing anything that even remotely looks like active defensive programming, then I catch myself, step back from my local problem, and realize I need to rethink the flow control of my application and probably either expand or deepen my supervision tree. I always tell people, "At this point Erlang feels less like a programming language to me and almost more like a mostly declarative DSL for creating distributed systems." :-)
That's truly one of the greatest things about OTP Supervisors in my opinion. When used diligently they really let you cleanly separate fault-tolerance concerns from your application code, and when doing code reviews they give you an immediately obvious place to start looking for leaky abstractions and tightly coupled subsystems.
There are 2-3 really good Elixir libraries around dates and times: calendar, goodtimes, etc.
Choice is great, but I really like a canonical library around something so core as time.