Correct. It should just work!

On Thu, Jun 20, 2024 at 18:26 Tobias Pfeiffer <prag...@gmail.com> wrote:

> Update: The OTP team implemented it! Should be coming to an erlang version
> near you soon. And I hope/think that elixir should automatically pick it up
> (@jose ?) https://github.com/erlang/otp/pull/8600
>
> On Mon, Jun 10, 2024 at 2:35 PM Tobias Pfeiffer <prag...@gmail.com> wrote:
>
>> To make it full circle, I've filed a feature request with erlang:
>> https://github.com/erlang/otp/issues/8558
>>
>> @Jason: Good point - thanks, I had forgotten that these are a thing. If
>> elixir was to consider this, I'd still vote for a warning though. Like, yes
>> technically it can match. Practically, I don't think these ill-formed
>> structs are something that is commonly used or the default that's expected.
>> And so, possibly degrading DX for them isn't great imo. It's also just  a
>> warning, and I think using them in this context is warning worthy :) And if
>> this was the behavior one wanted, one could just match against the
>> :__struct__ key. I also think that with the full complexity of this,
>> including it in something like credo is too much to ask - this is very much
>> a compiler/type checker concern as you need knowledge of the struct keys
>> etc.
>>
>> On Mon, Jun 3, 2024 at 6:40 PM Jason Axelson <jason.axel...@gmail.com>
>> wrote:
>>
>>> I quite like the idea of more compilation-warnings for impossible
>>> pattern matches! However, it does seem like a lot of work will be needed to
>>> get them reliable and performant enough to get there and I don't have any
>>> insight to add there.
>>>
>>> But I do want to point out that the "Map matching on struct specific
>>> keys" isn't an impossible match since not all structs are well-formed, e.g.
>>> the "range" function head can be hit like so:
>>> ```
>>> iex(1)> defmodule MapVsStruct do
>>> ...(1)>   def key_match(%{first: _first}), do: "map"
>>> ...(1)>   def key_match(%Range{}), do: "range"
>>> ...(1)> end
>>> {:module, MapVsStruct,
>>>  <<70, 79, 82, 49, 0, 0, 5, 188, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0,
>>> 0, 209,
>>>    0, 0, 0, 20, 18, 69, 108, 105, 120, 105, 114, 46, 77, 97, 112, 86,
>>> 115, 83,
>>>    116, 114, 117, 99, 116, 8, 95, 95, 105, ...>>, {:key_match, 1}}
>>> iex(2)> MapVsStruct.key_match(%{__struct__: Range})
>>> "range"
>>> ```
>>>
>>> So given that I'm not sure we'd want a compilation warning for that
>>> pattern match, so perhaps that warning would make more sense in a linter
>>> like Credo.
>>>
>>> -Jason
>>>
>>> On Thu, May 30, 2024 at 3:25 AM Tobias Pfeiffer <prag...@gmail.com>
>>> wrote:
>>>
>>>> Hello everyone,
>>>>
>>>> as usual thanks for all your outstanding work on Elixir & everything
>>>> else.
>>>>
>>>> Courtesy of a reddit discussion [1] I'd like to propose implementing
>>>> some more compiler warnings for matches that are impossible.
>>>>
>>>> ## Background
>>>>
>>>> Elixir is very programmer friendly and issues compiler warnings in many
>>>> cases if something is impossible. So if we match just against `variable` in
>>>> a function head and further down match against a more specific value we get
>>>> a warning.
>>>>
>>>> Similarly if we match against `__struct__` and the actual struct we get
>>>> a warning:
>>>>
>>>> def struct_match(%{__struct__: Range}), do: "__struct__"
>>>> def struct_match(%Range{}), do: "struct"
>>>>
>>>> This one warns as:
>>>>
>>>>     warning: this clause cannot match because a previous clause at line
>>>> 17 always matches
>>>>     │
>>>>  18 │   def struct_match(%Range{}), do: "struct"
>>>>     │   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>     │
>>>>     └─ lib/compiler_warnings_impossible_matches.ex:18
>>>>
>>>> This is great! The idea here is to take it further.
>>>>
>>>> ## Proposal
>>>>
>>>> The code examples used here can be found here:
>>>> https://github.com/PragTob/elixir_playground/blob/main/lib/compiler_warnings_impossible_matches.ex
>>>>
>>>> I tried the examples on 1.18.0-dev (ed67d6b) with OTP 27.0 to make sure
>>>> none of them emit a warning right now.
>>>>
>>>> In short, it's more warnings where for some of which I thought they'd
>>>> already warn you about impossible matches but found out they don't. I think
>>>> these warnings would be helpful to avoid bugs & help newcomers.
>>>>
>>>> ### Simple map match vs. Struct
>>>>
>>>> def map_match(%{}), do: "map"
>>>> def map_match(%Range{}), do: "range"
>>>>
>>>> Ideally this should warn as the match is impossible. Possibly also when
>>>> using the `is_map` guard.
>>>>
>>>> ### Map matching on struct specific keys
>>>>
>>>> def key_match(%{first: _first}), do: "map"
>>>> def key_match(%Range{}), do: "range"
>>>>
>>>> If we had a map where all keys overlap with a struct matched further
>>>> down in the function headers, ideally this should also warn. Of course, if
>>>> we add a second key to the match that the struct doesn't have it should not
>>>> warn.
>>>>
>>>> Of this proposal, I think this is the one that I see causing bugs most
>>>> easily.
>>>>
>>>> ### atoms, nil and booleans
>>>>
>>>> def atom_match(value) when is_atom(value), do: "atom"
>>>> def atom_match(nil), do: "nil"
>>>> def atom_match(value) when is_boolean(value), do: "bool"
>>>>
>>>> I'm not sure how much guards should be taken into account with these
>>>> kinds of warnings, but these are also "unmatchable".
>>>>
>>>> ## Implementation
>>>> I'm aware there is a chance you're aware of this and it wasn't
>>>> implemented for compilation performance considerations. If so, sorry and
>>>> happy to learn how I could look something like this up.
>>>>
>>>> If you agree that this could be worthwhile to implement, I'd be happy
>>>> to give the implementation a shot myself but I'd at least need basic
>>>> guidance as I don't know the internals all that well :)
>>>>
>>>> Thanks y'all and have a splendid day!
>>>>
>>>> [1] https://www.reddit.com/r/elixir/comments/1cibtia/comment/l2ckqjr/
>>>>
>>>> --
>>>> 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-core+unsubscr...@googlegroups.com.
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/elixir-lang-core/CAG3Z5YTVO1Wrvx76fg%2BBEmqC3PgZsRG0rEpLwVt7fdOWFZ8n2w%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAG3Z5YTVO1Wrvx76fg%2BBEmqC3PgZsRG0rEpLwVt7fdOWFZ8n2w%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>
>>>
>>>> --
>>> 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-core+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/elixir-lang-core/CAHMz6kwcOeu3aVrvbGQPN3t1DznfXwguMWwwEH8O7hgnU06O%3DA%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAHMz6kwcOeu3aVrvbGQPN3t1DznfXwguMWwwEH8O7hgnU06O%3DA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> 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-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CAG3Z5YS%2BOuMTorNWDA8H%3DO5p7z2%2BGWnyTL%3DOgW0uHxXcGsdTGw%40mail.gmail.com
> <https://groups.google.com/d/msgid/elixir-lang-core/CAG3Z5YS%2BOuMTorNWDA8H%3DO5p7z2%2BGWnyTL%3DOgW0uHxXcGsdTGw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LR8bcj1yEsk4XpQYxJuyeKvLD_RiDfrK1W0jGZgXR5CQ%40mail.gmail.com.

Reply via email to