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 <[email protected]>
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)
> "[email protected]" <[email protected]> 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 [email protected]
> > 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 [email protected]
> > > <[email protected]> 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 [email protected].
> > >> 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 • [email protected] • [email protected]
> > > 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 [email protected].
> 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 • [email protected] • [email protected]
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 [email protected].
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.