I remember benchmarking the iterators back when they were first introduced. My 
conclusion was that because they yield {key, value, next} tuples, while all 
elixir APIs expect {key, value} tuples, the packing & unpacking of those tuples 
becomes prohibitively expensive. This might no longer be an issue, so it could 
use some fresh benchmark, though I would be very surprised if things improved 
in any significant way.

Michał.

From: elixir-lang-core@googlegroups.com <elixir-lang-core@googlegroups.com>
Date: Thursday, 14 January 2021 at 08:46
To: elixir-lang-core@googlegroups.com <elixir-lang-core@googlegroups.com>
Subject: Re: [elixir-core:9957] [Proposal] Surface Erlang's maps:map function
Eksperimental, it is faster to build a list and call maps:from_list/1 than 
build the map as we go forward.

Also, please note maps:map/2 is implemented using maps:iterator/1 and 
maps:from_list/1: 
https://github.com/erlang/otp/blob/master/lib/stdlib/src/maps.erl#L374-L379 - 
so we can implement our own maps:map/2 that keeps our function arity.

All that said, if we want to make things faster, then we should evaluate 
changing Enumerable.Map to use iterators. But we would need extensive 
benchmarks to check if it is worth it.

On Thu, Jan 14, 2021 at 5:55 AM Austin Ziegler 
<halosta...@gmail.com<mailto:halosta...@gmail.com>> wrote:
Building `Map.new/2` on `maps:map/2` would be incompatible, because the 
transformation function differs in arity (`/1` for `Map.new/2` and `/2` for 
`maps:map/2`).

It would be possible to build `Map.new/2` such that it can tell the difference 
between a `/1` or a `/2` when the first function is itself a map or struct…but 
I’m not sure that would be an improvement, and it would lead to potentially 
confusing documentation on when a `/2` could be passed to `Map.new/2` and when 
a `/1` could be passed to `Map.new/2`.

If something is to be done, I believe that the original proposal, surfacing 
`maps:map/2` as `Map.map/2` with the arguments flipped for pipeline use _might_ 
be the best choice. At the same time, I’m not _entirely_ sure that would be 
useful, as most pipelines transform maps into lists and `maps:map/2` borks on a 
list:

```elixir
iex(1)> :maps.map(fn k, v -> v * 2 end, [{:a, 1}, {:b, 2}])
warning: variable "k" is unused (if the variable is not meant to be used, 
prefix it with an underscore)
  iex:1

** (BadMapError) expected a map, got: [a: 1, b: 2]
    (stdlib 3.12.1) maps.erl:247: :maps.map(#Function<13.126501267/2 in 
:erl_eval.expr/5>, [a: 1, b: 2])
```

At this point, even though I am happy to have discovered `maps:map/2` from this 
discussion, that this would _not_ improve the usability of Elixir on map 
transformation.

A different question: how can we make these rich Erlang functions much more 
visible to Elixir users like myself? I don’t care that the arguments are 
“backwards” from the pipeline, because `maps:map/2` is _incredibly_ useful and 
will improve some code that I have in production.

-a

On Wed, Jan 13, 2021 at 7:54 PM eksperimental 
<eksperimen...@autistici.org<mailto:eksperimen...@autistici.org>> wrote:
Great finding.
Regardless the benchmarks, Map.new/2 should be optimized for maps using
:maps.map/2, because as of now we are doing: map |> Enum.to_list() |>
reduce list |> :lists.reverse() |> :maps.from_list()

 On Tue, 12 Jan 2021 14:09:26 -0800 (PST)
"jonar...@gmail.com<mailto:jonar...@gmail.com>" 
<jonarnet...@gmail.com<mailto:jonarnet...@gmail.com>> wrote:

> This usage of Map.new/2 is news to me (pun somewhat intended) and
> pretty neat! However, I think that the naming alone may make it less
> discoverable and a bit harder to grok when first encountered. There
> also *might* be some performance gains from using Erlang's maps:map
> for this task instead of maps:from_list but I'm not sure. I'll do
> some profiling and find out.
>
> On Tuesday, January 12, 2021 at 5:01:51 PM UTC-5 
> halos...@gmail.com<mailto:halos...@gmail.com>
> wrote:
>
> > It’s not implemented with maps:map/2, but Map.new/2 should do the
> > trick.
> >
> > `Map.new(map, fn {k, v} -> {k, v * 2} end)`
> >
> > That said, `maps:map/2` is available:
> >
> > `:maps.map(fn _k, v -> v * 2 end, %{x: 1, y: 2, z: 3})`
> >
> > It might be worth exploring whether `Map.map` would be
> > useful/efficient enough to add for piping purposes.
> >
> > -a
> >
> > On Tue, Jan 12, 2021 at 4:51 PM 
> > jonar...@gmail.com<mailto:jonar...@gmail.com>
> > <jonar...@gmail.com<mailto:jonar...@gmail.com>> wrote:
> >
> >> A common task is to iterate over a map performing some operation
> >> thereby producing a new map. There are some ways to do this in
> >> Elixir presently, the simplest probably being for...into:
> >>
> >> for {key, val} <- map, into: %{} do
> >>   {key, val * 2}
> >> end
> >>
> >> Enum.reduce/3 is also an option. However, Erlang provides a simple
> >> function to replace the values of a map with maps:map function:
> >>
> >> maps:map(fun(Key, Val) -> 2 * Val end, Map)
> >>
> >> I think an equivalent of this in Elixir would be very useful
> >> either as Map.map/2 or Map.transform_values/2 like so:
> >>
> >> Map.transform_values(map, fn {_key, val} -> val * 2 end)
> >>
> >> I'm interested to hear if the community considers this a
> >> worthwhile addition!
> >>
> >> --
> >>
> > 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<mailto:elixir-lang-co...@googlegroups.com>.
> >> To view this discussion on the web visit
> >> https://groups.google.com/d/msgid/elixir-lang-core/d843c44b-e658-4d71-bb66-00c1e0a21ef7n%40googlegroups.com
> >> <https://groups.google.com/d/msgid/elixir-lang-core/d843c44b-e658-4d71-bb66-00c1e0a21ef7n%40googlegroups.com?utm_medium=email&utm_source=footer>
> >> .
> >>
> >
> >
> > --
> > Austin Ziegler • halos...@gmail.com<mailto:halos...@gmail.com> • 
> > aus...@halostatue.ca<mailto:aus...@halostatue.ca>
> > http://www.halostatue.ca/http://twitter.com/halostatue
> >
>

--
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<mailto:elixir-lang-core%2bunsubscr...@googlegroups.com>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/5fff9633.1c69fb81.eec7e.37f2SMTPIN_ADDED_MISSING%40gmr-mx.google.com.


--
Austin Ziegler • halosta...@gmail.com<mailto:halosta...@gmail.com> • 
aus...@halostatue.ca<mailto:aus...@halostatue.ca>
http://www.halostatue.ca/http://twitter.com/halostatue
--
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<mailto:elixir-lang-core+unsubscr...@googlegroups.com>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAJ4ekQvW-UNQC3pORyb-D4hGCTPvupkT%2Bp53KSkTj8bknj%3Dqgg%40mail.gmail.com<https://groups.google.com/d/msgid/elixir-lang-core/CAJ4ekQvW-UNQC3pORyb-D4hGCTPvupkT%2Bp53KSkTj8bknj%3Dqgg%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-core+unsubscr...@googlegroups.com<mailto:elixir-lang-core+unsubscr...@googlegroups.com>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LKSMDNM%3DbvXg68tpgQzqMxPEBaVzf96dishNuhutcCsg%40mail.gmail.com<https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LKSMDNM%3DbvXg68tpgQzqMxPEBaVzf96dishNuhutcCsg%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-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/DB7PR07MB38993DAE97190A63FBD5FD14FAA80%40DB7PR07MB3899.eurprd07.prod.outlook.com.

Reply via email to