I think this would be a great addition to the core.
While there are libraries in this space, as silly as this may seem, solving
this key typo problem seems like solving the 60%-80% case (not to take away
anything from those libraries!)
How about a Keyword.take!/2?
iex> Keyword.take!([a: 1], [:a, :b])
[a: 1]
iex> Keyword.take!([c: 1], [:a, :b])
** (ArgumentError) unknown key :c in [c: 1]
There are however two problems with it:
1. would people expect that `Keyword.take!([a: 1], [:a, :b])` should fail
because `:b` is not in the input?
Maybe the 2nd argument accepts defaults? (I know it probably starts doing
too much...)
iex> Keyword.take!([a: 1], [:a, :b])
[a: 1, b: nil]
iex> Keyword.take!([a: 1], [:a, b: 2])
[a: 1, b: 2]
In fact this could have the following semantics: if there's no default, it's
a required key:
iex> Keyword.take!([], [:a, b: 2])
** (ArgumentError) missing required key :a
What's nice is you can later use `Keyword.fetch!/2` that will save you from
typos.
But that being said, If the 2nd argument accepts a keyword, then it
probably shouldn't be called `take!/2` as it no longer matches `take/2`.
2. If you do: `opts = Keyword.take!(..., ...)` and later `opts[:my_key]` you
still have an opportunity for a typo and you can't necessarily use
`Keyword.fetch!/2` because optional keys might not be there.
As Devon mentioned, structs are a really cool solution because they provide
rigidity, defaults, and the assertive map access syntax with ".". Creating a
struct for every function that accepts options feels like a bit much though.
Taking everything above into consideration, perhaps there's:
iex> Map.something_something!([], [:name, timeout: 5000])
** (ArgumentError) missing required key :name
iex> opts = Map.something_something!([name: Foo], [:name, timeout: 5000])
iex> opts.timeout
5000
and I feel like it's still relatively small addition but it's closer to the
"80% solution". No idea how to name this thing though!
> On 30 Dec 2020, at 09:36, Devon Estes <[email protected]> wrote:
>
> Typos are extremely hard to prevent in dynamic data structures since
> validations need to be implemented at the point of use instead of at the
> point of creation/definition of the structure. What would stop the developer
> from writing the typo in their validation, as José did in his example?
>
> It seems to me like if the goal is to prevent typos then a struct would be
> the way to go.
>
> Kurtis Rainbolt-Greene <[email protected]> schrieb am Mi. 30.
> Dez. 2020 um 09:29:
> Yes, but think of the valuable hours saved and the amount of code that won't
> have to be written.
>
> I mean even Valim's own example again has the typo.
>
> On Tue, Dec 29, 2020 at 11:58 PM Andrea Leopardi <[email protected]
> <mailto:[email protected]>> wrote:
> Considering how straightforward the code you showed is, and that for more
> complex scenarios we have libraries like nimble_options, I might be slightly
> hesitant to add this to core.
>
> Andrea
>
> On Wed, 30 Dec 2020 at 08:53, José Valim <[email protected]
> <mailto:[email protected]>> wrote:
> Hi everyone,
>
> I am working on a new project and yesterday I spent a couple hours on a bug
> due to a in a keyword list. In a nutshell, I was supposed to pass
> parenthesis: 10 as keywords to a function but I passed parentheses: 10.
>
> I have fixed the issue by adding the following code:
>
> for {k, _} <- keyword, k not in [:parentheses, :other_options], do: raise
> "unknown key #{inspect(k)} in #{inspect(keyword)}"
>
> The code is super straight-forward but I am wondering if we should add it to
> Elixir to promote said validation. What do you think? Any suggestions on
> where it should be defined and with which name?
>
> Thank you!
>
>
> --
> 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 [email protected]
> <mailto:[email protected]>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4J8_RG5eeCZSw_c75Q4y19YFt-ipdnTAEa1cE2GnvwjrQ%40mail.gmail.com
>
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4J8_RG5eeCZSw_c75Q4y19YFt-ipdnTAEa1cE2GnvwjrQ%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 [email protected]
> <mailto:[email protected]>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CAM9Rf%2BJPu8tF2VzNB4beDqO9jc%2BF-SDE6u%3D724EZm9271jY2ug%40mail.gmail.com
>
> <https://groups.google.com/d/msgid/elixir-lang-core/CAM9Rf%2BJPu8tF2VzNB4beDqO9jc%2BF-SDE6u%3D724EZm9271jY2ug%40mail.gmail.com?utm_medium=email&utm_source=footer>.
>
>
> --
> Kurtis Rainbolt-Greene,
> Software Developer & Founder of Difference Engineers
> 202-643-2263
>
> --
> 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 [email protected]
> <mailto:[email protected]>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CAMhJPGiKh3uOaY2UNDFYu9x64n-mM7Sqf7iHU09QeAmfOY0mwQ%40mail.gmail.com
>
> <https://groups.google.com/d/msgid/elixir-lang-core/CAMhJPGiKh3uOaY2UNDFYu9x64n-mM7Sqf7iHU09QeAmfOY0mwQ%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> --
>
> _________________
> Devon Estes
> +49 176 2356 4717
> www.devonestes.com <http://www.devonestes.com/>
>
>
> --
> 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 [email protected]
> <mailto:[email protected]>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CAGowJcg_DWYAQsys5f6Ad1nYket8be1Lsrmui8Uh%3DzEAKzWzTQ%40mail.gmail.com
>
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGowJcg_DWYAQsys5f6Ad1nYket8be1Lsrmui8Uh%3DzEAKzWzTQ%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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/5E7686D9-1DC6-4830-8C32-7FCAFFE6E706%40wojtekmach.pl.