I think having a function in the shape of List.key* but one that assumes a
certain shape (i.e. a two-element tuple) is counter-intuitive. We could
have List.keyfind!(...) but it should still return a tuple in case of
success. :)

On Tue, Jul 6, 2021 at 1:38 PM Wojtek Mach <woj...@wojtekmach.pl> wrote:

> When working with lists of two element tuples like:
>
>     headers = [{"content-type", "html"}]
>     attributes = [{"href", "https://elixir-lang.org"}]
>
> I'd usually access the value like this:
>
>     {_, content_type} = List.keyfind(headers, "content-type", 0)
>     IO.puts content_type
>
> And when the value is not there, I'd get:
>
>     ** (MatchError) no match of right hand side value: nil
>
> I'd like to propose adding a new function so instead we could do:
>
>     IO.puts List.keyfetch!(headers, "content-type")
>
> This function can give a better error message and is pipe friendly. It
> only works on lists with k/v, hence using the word fetch which reminds us
> of `Map.fetch`, `Keyword.fetch`, etc.
>
> ## Example implementation
>
>     def keyfetch!(list, key) do
>       case List.keyfind(list, key, 0) do
>         {_, value} ->
>           value
>
>         nil ->
>           raise "key not found: #{inspect(key)}"
>
>         tuple ->
>           raise "expected list to contain two-element tuples, got:
> #{inspect(tuple)}"
>       end
>     end
>
> ## Q & A
>
> Q: Why not `List.keyfind!(list, key, position)` that returns the value?
>
> A: The crux of the proposal is to be able to do this:
>
>     List.keyfind!([{"a", 1}], "a", 0)
>     #=> 1
>
> But given it is called `keyfind` we should also handle this and it is
> unclear what
> it should return:
>
>     List.keyfind!([{"a", 1, 2}], "a", 0)
>     #=> ???
>
> Q: Why not `List.keyfind!(list, key, position)` that returns the tuple?
>
> A: I think that'd be an improvement although we'd still have to manually
> unpack the value which is a bit annoying.
>
> Q: Why not `List.keyfetch!(list, key, position \\ 0)`?
>
> A: I'd be ok with that.
>
> Q: Should there also be a non-raising variant, `List.keyfetch(list, key)`?
>
> A: In that case I think it's fine to pattern match on `List.keyfind/3` but
> yeah, I could see it added for consistency.
>
> --
> 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/f82edae0-c129-4d39-946e-7f15576f271an%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/f82edae0-c129-4d39-946e-7f15576f271an%40googlegroups.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/CAGnRm4JYyEbX_QLMAqnaa6mo8mOd_iy0eSc876_i5R9omMgc4w%40mail.gmail.com.

Reply via email to