Hi all,
Hopefully this isn't too large a tangent:
One thing that I have consistently found in my projects is that error handling is very tedious in my elixir projects. A typical workflow of mine is some outer function has a public interface and needs to return either the success case, or an {:error, reason} tuple.
How I usually go about solving that is that at every level of this pipeline, I have code that has a with {:ok, a} <-some_function(), {:ok, b} <- other_function(a) do {:ok, b}. I then end up needing to 1) Repeat this with pipeline throughout my codebase wherever there are failure conditions and 2) be precise about my else case to make sure I return the correct error condition.
Often I end up with a helper function that returns {:error, :reason_a}, but is called in two contexts. In a different context, when this error happens, {:error, :reason_b} should be returned. Thus, I need to have code written like else {:error, :reason_a} -> {:error, :reason_b} in my code. This also happens somewhat frequently when calling third party libraries and needing to wrap the error semantics in a common layer.
Elixir discourages the pattern of raising exceptions, which makes a lot of sense from a functional perspective, so that avenue seems out (except for, well, exceptional cases). I bring this up because other languages use namespacing or OO inheritance to classify different types of errors which allows for more streamlined handling.
All this is to say that I think there is value in adding a more opinionated error handling pattern to elixir. This would have the benefit of a consistent pattern that would allow libraries to chain together easily. I don't have a built out proposal, but my rough thoughts involve an `Error` module with the concept of namespacing an error. E.g. something like %Error{type: :runtime_error.input_validation.out_of_range, source: :my_library, extra: %{}} and associated helper functions & pipelines to handle this.
Again, I don't have a concrete proposal, and even if I did, it would make more sense to experiment with this as a 3rd party library first. Hopefully this post adds to the perspective that error handling is tedious and it would be great to look at ways to alleviate this pain point.
Best regards,
Anil Kulkarni
On 4/16/19, 5:26 PM, "
elixir-l...@googlegroups.com on behalf of Greg Vaughn" <
elixir-l...@googlegroups.com on behalf of
gva...@gmail.com> wrote:
José, you are so gracious in dealing with the Elixir community. I appreciate that very much. It has inspired me to work to be more gracious in my own life.
-Greg Vaughn
> On Apr 16, 2019, at 7:18 PM, José Valim <
jose....@plataformatec.com.br> wrote:
>
> Hi Tom,
>
> You probably meant it as a joke but just keep in mind jokes do not translate well to text.
>
> Evaluating the language proposals is often tiresome and it is work that is not always appreciated, so it is probably best for everyone to stay in topic.
>
> Thanks,
>
> On Wed, Apr 17, 2019 at 02:03 <
t...@scalpel.com> wrote:
> Ok we'll paint the bikeshed green.
>
> On Tuesday, April 16, 2019 at 7:36:51 PM UTC-4, José Valim wrote:
> They probably shouldn't been lists in the first place but that ship sailed a long time ago.
>
> If you need to work with them dynamically, the API is there. It just shouldn't be encouraged and adding functions such as Tuple.wrap could end-up having the opposite effect: encouraging more dynamic work making everyone's life harder, rather than easier.
>
>
> José Valim
>
www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
>
> On Wed, Apr 17, 2019 at 1:32 AM <
t...@scalpel.com> wrote:
> I agree that they are rarely used dynamically, but when they are they can be quite the pain to work with.
>
> For example, if you are doing any work with ASN.1 dynamic tuples are everywhere. Any advanced work in cryptography or telecom becomes harder to work with than I would like it to be.
>
> On Tuesday, April 16, 2019 at 7:24:15 PM UTC-4, José Valim wrote:
> Well, the difference is really in their usage. Tuples are rarely used dynamically, you usually want to see tuples as literals in your code. The Tuple docs also mention it:
>
> > The functions in this module that add and remove elements from tuples are
> > rarely used in practice, as they typically imply tuples are being used as
> > collections. To append to a tuple, it is preferable to use pattern matching
>
>
> José Valim
>
www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
>
> On Wed, Apr 17, 2019 at 1:20 AM <
t...@scalpel.com> wrote:
> I see your point.
>
> I was thinking more along the lines of consistency in the API design. If you can wrap an item in a list why can't you wrap it in a tuple? If you could wrap things in tuples then you could insert a value at the front of said tuple.This is more of an exercise in "you could" rather than "you should".
>
> On Tuesday, April 16, 2019 at 7:07:33 PM UTC-4, José Valim wrote:
> If the choice is between:
>
> value |> Tuple.wrap() |> Tuple.insert_at(0, :ok)
>
> and
>
> {:ok, value}
>
> I believe we should choose the second every time.
>
> If the choice is between:
>
> value
> |> very()
> |> long()
> |> pipeline()
> |> Tuple.wrap()
> |> Tuple.insert_at(0, :ok)
>
> and:
>
> value
> |> very()
> |> long()
> |> pipeline()
> |> OkError.ok()
>
> and:
>
> var =
> value
> |> very()
> |> long()
> |> pipeline()
>
> {:ok, var}
>
> I don't see any reason why we should ever do the first one.
>
> So I really don't see which problem Tuple.wrap is supposed to solve.
>
> José Valim
>
www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
>
> On Wed, Apr 17, 2019 at 12:58 AM <
t...@scalpel.com> wrote:
> I understand that this is possible, and thank you for the suggestion but I'm not the biggest fan of anonymous functions.
>
> When I go back and read programs written this way I can't tell if I wrote the code or a cat walked on my keyboard.
>
> On Tuesday, April 16, 2019 at 6:54:16 PM UTC-4, Ryan Winchester wrote:
> Yeah, sorry
>
> value |> (&{:ok, &1}).()
>
> On April 16, 2019 at 3:51:28 PM, Ryan Winchester (
he...@ryanwinchester.ca ) wrote:
>
>> value |> (&{&1}).() |> Tuple.insert_at(0, :ok)
>>
>> On April 16, 2019 at 3:47:58 PM,
t...@scalpel.com (
t...@scalpel.com ) wrote:
>>
>>> Fair enough, I know when to give up on a losing battle.
>>>
>>> Would you consider an alternative like Tuple.wrap/1. It would work exactly like List.wrap/1 but doesn't carry the baggage that "error" and "ok" would have. This way I could still accomplish the goal of keeping pipe chains clean with something like.
>>>
>>> value |> Tuple.wrap() |> Tuple.insert_at(0, :ok)
>>>
>>> Which is a bit wordier but functionally equivalent to the original proposal.
>>>
>>> On Tuesday, April 16, 2019 at 6:04:55 PM UTC-4, José Valim wrote:
>>> Hi Tom,
>>>
>>> You don't have to buy the arguments, we can agree to disagree, but they are still the reason for not adding such functions to Elixir. :)
>>>
>>> I also agree with is_even and is_odd being similar convenience functions but they do have a rationale. They were added before defguard existed. At the time, writing guards was a bit more bureaucratic. But if is_odd/is_even were proposed today, they would most likely have been rejected as well.
>>>
>>> Elixir already has a perfectly fine syntax via curly brackets for creating ok and error tuples, that also works on matching, so my recommendation is still to build an extra vocabulary in your app or as a separate library.
>>>
>>> José Valim
>>>
www.plataformatec.com.br
>>> Skype: jv.ptec
>>> Founder and Director of R&D
>>>
>>>
>>> On Tue, Apr 16, 2019 at 11:46 PM <
t...@scalpel.com > wrote:
>>> I disagree that this should be a library. (I've already done this in my app and would be fine extracting it into one though) I don't buy the slippery slope argument. The functions are very simple to create and maintain, and it's not like the Tuple module is overflowing with complexity. We have things like 'is_even' and 'is_odd' because they are common to work with. :ok and :error are insanely common in elixir codebases. Why not add convenience methods?
>>>
>>> On Tuesday, April 16, 2019 at 5:22:38 PM UTC-4, José Valim wrote:
>>> Hi Tom, thanks for the proposal.
>>>
>>> As OvermindDL1 already hinted, this can lead to a slippery slope where we need to add bang variants, question mark variants, ok/1/2/3/4 to deal with arities and so on. I would suggest building this vocabulary as necessary in your applications or, if you want to share it with the world, it could be a nice library. Hint: the package ok_error seems to be available. :)
>>>
>>> José Valim
>>>
www.plataformatec.com.br
>>> Skype: jv.ptec
>>> Founder and Director of R&D
>>>
>>>
>>> On Tue, Apr 16, 2019 at 11:12 PM OvermindDL1 <
overm...@gmail.com > wrote:
>>> On Tuesday, April 16, 2019 at 3:04:13 PM UTC-6,
t...@scalpel.com wrote:
>>> It is often the case that you want to wrap the result of an operation in an ":ok" or ":error" Tuple. We should add convenience wrapper functions since this is so common and it cleans up otherwise ugly code.
>>>
>>> def ok(value), do: {:ok, value}
>>> def error(value), do: {:error, value}
>>>
>>> This could be quite useful! On the other side it would be useful to add functions like these as well:
>>>
>>> def ok!({:ok, value}), do: value
>>>
>>> def ok?({:ok, _value}), do: true
>>> def ok?(_), do: false
>>>
>>> And so forth for error as well. They are not really useful on their own because matching is better, but for use in pipes that would be quite useful (right now I use the exceptional library, which does similar things and more).
>>> --
>>> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an email to
elixir-l...@googlegroups.com .
>>> To view this discussion on the web visit
https://groups.google.com/d/ msgid/elixir-lang-core/ 30614530-7e33-4cb8-bffb- 63c18248d340%40googlegroups. com .
>>> For more options, visit
https://groups.google.com/d/ optout .
>>> --
>>> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an email to elixir-l...@
googlegroups.com .
>>> To view this discussion on the web visit
https://groups.google.com/d/ msgid/elixir-lang-core/ 0314757d-eff2-4b23-8130- a19ee921b254%40googlegroups. com .
>>> For more options, visit
https://groups.google.com/d/ optout .
>>> --
>>> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an email to
elixir-l...@googlegroups.com .
>>> To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/2e7204c7-6d06-49f9-8edc-7c631f75063a%40googlegroups.com .
>>> For more options, visit
https://groups.google.com/d/optout .
>
> --
> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to
elixir-l...@googlegroups.com.
> To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/721abcf1-0cfd-4824-b54a-ff2aa22487f3%40googlegroups.com.
> For more options, visit
https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to
elixir-l...@googlegroups.com.
> To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/5607dc54-2c5d-452c-a5a5-fa6ec03864c3%40googlegroups.com.
> For more options, visit
https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to
elixir-l...@googlegroups.com.
> To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/50776062-e75d-4f31-8266-2b633e78bf89%40googlegroups.com.
> For more options, visit
https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to
elixir-lang-co...@googlegroups.com.
> To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/f1c5a753-6964-466b-aabb-5f8cdb7c7ec0%40googlegroups.com.
> For more options, visit
https://groups.google.com/d/optout.
> --
>
>
> José Valim
>
www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
> --
> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to
elixir-lang-co...@googlegroups.com.
> To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2Bmvy5%3DC3cgwMPquPsrM32JjNdn0mxdsvOthLt0eXU4yg%40mail.gmail.com.
> For more options, visit
https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/0482DC4E-5021-44C1-846C-ABABF265BAD3%40gmail.com.
For more options, visit
https://groups.google.com/d/optout.