Wojtek, I originally thought about Map.merge!, where the second argument must be a subset of the first. This way we can check keys and provide default values:
Keyword.merge!([parenthesis: 10], opts) However, when I tried using this in practice, I realized that default arguments are not always straight-forward to compute. For example, you may want to compute them lazily. You could argue we could set them to nil in said cases, but then we'd mix the absence of a key with nil value, which may not be desired. Therefore, I concluded that it is probably best to keep those problems separated and validate only the keys. I agree with Andrea that this is small but the benefit I see having it in core is to promote more folks to use it. Both Python and Ruby provide at the syntax-level a convenience that checks only the given keys are expected. So, when it comes to options, both of these languages are allowing us to write assertive code more elegantly than Elixir. On Wed, Dec 30, 2020 at 10:10 AM Wojtek Mach <[email protected]> wrote: > 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]> >> 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]> 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]. >>>> 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]. >>> 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]. >> 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 > > > -- > 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/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 > <https://groups.google.com/d/msgid/elixir-lang-core/5E7686D9-1DC6-4830-8C32-7FCAFFE6E706%40wojtekmach.pl?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/CAGnRm4%2B9YG1YwoK9JGAitzOzikOeo4dXCHyvu%3DjAU6SN1HRocw%40mail.gmail.com.
