The issue is that for take!, I can see two semantics:

1. The map/keyword must have all of the given keys
2. The map/keyword must have at most the given keys

And I think 1) makes more sense intuitively. :(

On Wed, Dec 30, 2020 at 11:48 AM Wojtek Mach <[email protected]> wrote:

> Fair enough, agreed about decoupling the problem. In that case I’d still
> offer
> Keyword.take!/2 that works like this:
>
>    iex> Keyword.take!([a: 1], [:a, :b])
>    [a: 1]
>
>    iex> Keyword.take!([c: 1], [:a, :b])
>    ** (ArgumentError)
>
> I think take/2 and take!/2 matches struct/2 and struct!/2.
>
> On 30 Dec 2020, at 11:30, José Valim <[email protected]> wrote:
>
> 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
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2B9YG1YwoK9JGAitzOzikOeo4dXCHyvu%3DjAU6SN1HRocw%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/2A76D025-BF9B-45E1-B268-DD23753FEC6C%40wojtekmach.pl
> <https://groups.google.com/d/msgid/elixir-lang-core/2A76D025-BF9B-45E1-B268-DD23753FEC6C%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/CAGnRm4Jx0-0xU76qaury3k5P8WuKjNRj8xUKj1Cz8a0YyuX%2BMA%40mail.gmail.com.

Reply via email to