So the original proposal here is for introducing a named parameter syntax. 
The reason I like named parameters is b/c the order of parameters doesn't 
matter – when they do matter it's easy for refactoring to introduce hard to 
catch bugs. Pattern matching has been proposed as the idiomatic way to 
achieve argument order not mattering. If I understand correctly, the 
recommendation is to stuff arguments into a map just before a function call 
that itself immediately destructures them. While this approach does address 
my primary concern (ie parameter order), it has to be slower, right? I can 
imagine this having a non-trivial effect in a pipeline on a hot-path.

So the question for me, really, is how much quicker is passing ordered 
arguments vs creating then destructuring a map? If it's negligible then 
it's negligble, but if it's not then it would be nice to have an 
alternative.

- Jake

On Friday, October 28, 2022 at 9:47:31 AM UTC-4 José Valim wrote:

> > Is this an expensive pattern because it generates a map only for the 
> next function to extract the keys and ignore the map?
>
> It depends on what you are comparing it with. Compared to simply passing 
> arguments, it is likely slower. Compared to keyword lists, likely faster.
>
> On Fri, Oct 28, 2022 at 3:41 PM Brandon Gillespie <bra...@cold.org> wrote:
>
>> Fair enough :)
>>
>> If I understand what you are saying: they are all maps because the source 
>> data comes from a map, and it's the method of extracting data from the map 
>> that differs (the algorithm), not the inherent nature of a map itself.
>>
>> I agree, and apologize for the mistaken assertion.
>>
>> However, what I didn't benchmark as i think about it, is what I often 
>> will see, which is the creation of a map simply to pass arguments — and 
>> this is more relevant to the request/need. The example was based on 
>> existing structs/maps and not creating them at each function call time.
>>
>> Instead, for example:
>>
>>        def do_a_thing(%{key2: value2, key1: value1}) do ...
>>
>> I think it's becoming a common pattern to then construct the maps as part 
>> of the call, ala:
>>
>>        do_a_thing(%{key1: 10, key2: 20})
>>
>> Is this an expensive pattern because it generates a map only for the next 
>> function to extract the keys and ignore the map?
>>
>> -Brandon
>>
>>
>> On 10/28/22 12:37 AM, José Valim wrote:
>>
>>  
>>
>>> 1.79 times, as I read it, not 1.79us. And of course benchmarks being 
>>>> highly subjective, now that I retooled it it's at 2.12x slower (see notes 
>>>> at the very bottom for likely reasons why).
>>>>
>>> Correct. What I did is to take a reference value of 1us and multiplied 
>> it by 1.79, to say that at this scale those numbers likely won't matter. 
>>
>>> The gist includes three scenarios: 
>>>>
>>> Thanks for sharing. I won't go deep into this, as requested, but I want 
>> to point out that the conclusion "maps are slower (significantly enough to 
>> avoid)" is still incorrect for the benchmarks above.
>>
>> All of those benchmarks are using map patterns because both map.field and 
>> Map.get are also pattern matching on maps.
>>
>> map.field is equivalent to:
>>
>> case map do
>>   %{field: value} -> value
>>   %{} -> :erlang.error(:badkey)
>>   _ -> :erlang.error(:badmap)
>> end
>>
>> Map.get/2 is equivalent to:
>>
>> case map do
>>   %{field: value} -> value
>>   %{} -> nil
>> end
>>  
>> To further drive this point home, you could rewrite the map_get one as:
>>
>>   def map_get(engine) do
>>     map_get_take(engine.persist, engine, @take_keys, [])
>>   end
>>
>>   defp map_get_take(engine, persist, [a | rest], out) do
>>     case {engine, persist} do
>>       {%{^a => value}, %{^a => value}} ->
>>         map_get_take(engine, persist, rest, [{a, value} | out])
>>
>>       _ ->
>>         map_get_take(engine, persist, rest, out)
>>     end
>>   end
>>
>>   defp map_get_take(_, _, [], out), do: out
>>
>> And the numbers likely won't matter or be roughly the same. The point is: 
>> you are effectively benchmarking different algorithms and not the 
>> difference between map_get or map_pattern.
>>
>> I am only calling this out because I want to be sure no one will have 
>> "maps are slower (significantly enough to avoid)" as a take away from this 
>> discussion.
>>
>> > What if a syntax for matching on keyword lists that allowed for items 
>> in any position was added to Elixir? Something like (just shooting from the 
>> hip) `[…foo: bar]` ? Then you could have your cake and eat it too, right?
>>
>> Valid patterns and guards are dictated by the VM. We can't compile 
>> keyword lists lookups to any valid pattern matching and I would be 
>> skeptical about proposing such because we should avoid adding linear 
>> lookups to patterns.
>>
>> It is worth taking a step back. It is not only about asking "can we have 
>> this feature?". But also asking (at least) if the feature plays well with 
>> the other constructs in the language and if we can efficiently implement it 
>> (and I believe the answer is no to both).
>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "elixir-lang-core" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/elixir-lang-core/Dbl6CL5TU5A/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to 
>> elixir-lang-co...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4L37yu8KVbhuM0gNkVYOzCeoXaKzTBk4aY4OLLRdgRRLg%40mail.gmail.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4L37yu8KVbhuM0gNkVYOzCeoXaKzTBk4aY4OLLRdgRRLg%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 elixir-lang-co...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/9f60ba0c-8403-e93f-d5fb-b3f55df88d14%40cold.org
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/9f60ba0c-8403-e93f-d5fb-b3f55df88d14%40cold.org?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/01432858-e854-4747-921a-230e6bbd7489n%40googlegroups.com.

Reply via email to