> There are already a ton of ways to validate presence of keys at runtime -
Keyword.fetch!/2, Keyword.has_key?/2, Keyword.update!/3, Keyword.replace!/3
- all of which would spot a typo. What would this really add that would
provide meaningful feedback that those other functions don’t offer?

This is not the problem that I originally reported though, is it? We don't
want to check if a key exists, we want to check there is no other key
beyond the given set.

On Wed, Dec 30, 2020 at 6:48 PM Zach Daniel <[email protected]>
wrote:

> What would be really awesome is some kind of "rubric" for answering the
> question "does this belong in the standard library". It could be as simple
> as something like a set of criteria like "ubiquity", "utility", "new value
> add", and some scores that it needs to exceed, e.g perhaps greater than a
> 7/10 for each. I think that we could grade it without worrying about the
> name, and then have freeform discussion around naming it once we've decided
> that the function itself belongs in the standard library. This would have
> two benefits: structuring the conversation around changes to the standard
> library, and letting people evaluate their idea against that rubric before
> submitting it. I get that adding extra structure/process around things can
> be annoying, but the "should we put X in the standard library" conversation
> is one that comes up enough to potentially warrant it.
>
> On Wed, Dec 30, 2020 at 12:38 PM Devon Estes <[email protected]>
> wrote:
>
>> There are already a ton of ways to validate presence of keys at runtime -
>> Keyword.fetch!/2, Keyword.has_key?/2, Keyword.update!/3, Keyword.replace!/3
>> - all of which would spot a typo. What would this really add that would
>> provide meaningful feedback that those other functions don’t offer?
>>
>> I see the bigger issue is that developers need to opt into that feedback
>> by using those functions instead of the others that „fail“ in more quiet
>> ways. Adding more ways to do this type of validation won’t necessarily mean
>> that developers would be any more likely to use them.
>>
>> José Valim <[email protected]> schrieb am Mi. 30. Dez. 2020 um 17:43:
>>
>>> > But if we want to solve this problem as it was stated (how to give
>>> faster feedback about typos) then the only thing I can see that would
>>> actually solve the problem and let the developer know they have a typo is
>>> to use a struct or to add some additional syntax for passing named
>>> arguments to functions that could be checked at compile time and could
>>> validate that the needed keys are passed.
>>>
>>> I don't think the problem needs to be solved at compile-time. Definitely
>>> it would be best but getting feedback at runtime is better than getting no
>>> feedback at all.
>>>
>>> On Wed, Dec 30, 2020 at 5:36 PM Devon Estes <[email protected]>
>>> wrote:
>>>
>>>> I don’t think the issue is with fetching the values, as we already have
>>>> Keyword.fetch!/2. The root cause of the issue is that there is connascence
>>>> of name between disparate places about the specific values in a
>>>> dynamic, unstructured data structure, and that there is no way currently to
>>>> programmatically check that connascence of name because of the dynamic
>>>> nature of a keyword list. Adding a new function like this might feel good,
>>>> and it might even be a helpful selling point to people, but it won’t
>>>> actually solve the problem.
>>>>
>>>> If we want to have some concept of named arguments to a function like
>>>> Ruby & Python do, then that‘s a thing I can get behind, but that‘s not what
>>>> keyword lists are for and would need to be done in a different manner (and
>>>> would likely require different/new syntax).
>>>>
>>>> Also, if we want to add functions like this because they _look_ like
>>>> they‘ll be helpful (even if they might not really be), and that this will
>>>> make the language more appealing to folks, I can get behind that as well as
>>>> long as folks acknowledge that this won’t actually solve the problem.
>>>>
>>>> But if we want to solve this problem as it was stated (how to give
>>>> faster feedback about typos) then the only thing I can see that would
>>>> actually solve the problem and let the developer know they have a typo is
>>>> to use a struct or to add some additional syntax for passing named
>>>> arguments to functions that could be checked at compile time and could
>>>> validate that the needed keys are passed.
>>>>
>>>> Michał Muskała <[email protected]> schrieb am Mi. 30. Dez. 2020 um
>>>> 17:17:
>>>>
>>>>> I presume after validating the options, you’ll have to access them.
>>>>> Why not combine the two? Something like:
>>>>>
>>>>>
>>>>>
>>>>>     [parentheses, other_option] = Keyword.fetch_exact!(opts,
>>>>> [:parentheses, :other_option])
>>>>>
>>>>>
>>>>>
>>>>> Perhaps even supporting defaults:
>>>>>
>>>>>
>>>>>
>>>>>     [other_option, parentheses] = Keyword.fetch_exact!(opts,
>>>>> [:other_option, parentheses: false])
>>>>>
>>>>>
>>>>>
>>>>> The name, of course, has to improve, but I think functionality-wise a
>>>>> function like this would be really useful.
>>>>>
>>>>>
>>>>>
>>>>> Michał.
>>>>>
>>>>>
>>>>>
>>>>> *From: *[email protected] <
>>>>> [email protected]>
>>>>> *Date: *Wednesday, 30 December 2020 at 10:53
>>>>> *To: *[email protected] <
>>>>> [email protected]>
>>>>> *Subject: *Re: [elixir-core:9918] Validating keywords keys
>>>>>
>>>>> 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
>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Jx0-0xU76qaury3k5P8WuKjNRj8xUKj1Cz8a0YyuX%2BMA%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/DB7PR07MB3899661710E2B7CE05CD82A0FAD70%40DB7PR07MB3899.eurprd07.prod.outlook.com
>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/DB7PR07MB3899661710E2B7CE05CD82A0FAD70%40DB7PR07MB3899.eurprd07.prod.outlook.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/CAGowJciiAumHzprUfvpKKPQ_DG9dR44oCkuc_Kam%3DQCaSVWA-Q%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGowJciiAumHzprUfvpKKPQ_DG9dR44oCkuc_Kam%3DQCaSVWA-Q%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/CAGnRm4JxykeSzY3XCqA31ghQjx6TrqUA8w%3DEQ5mO4KXGLXPM1Q%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JxykeSzY3XCqA31ghQjx6TrqUA8w%3DEQ5mO4KXGLXPM1Q%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/CAGowJchNAD8k5YT3HHv7NRv1EJbLop7NPLuUy6fqoKmyPxskgQ%40mail.gmail.com
>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGowJchNAD8k5YT3HHv7NRv1EJbLop7NPLuUy6fqoKmyPxskgQ%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/CAK-yb0AMW7m38H6OOyT0K%3DL4Usn1Vqv2QBKzkepJ3Hp54Wt%2Bhg%40mail.gmail.com
> <https://groups.google.com/d/msgid/elixir-lang-core/CAK-yb0AMW7m38H6OOyT0K%3DL4Usn1Vqv2QBKzkepJ3Hp54Wt%2Bhg%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/CAGnRm4J9wyBWCr3uyhmKkiM4cp2r1%3DNXOSY_h7d6%2Bm5xHFk9nA%40mail.gmail.com.

Reply via email to