The arity issue can be dealt internally.

def new(map, transform) when is_map(map) and is_function(transform, 1)
do
:maps.map( fn key, val ->
      {_new_key, new_value} = transform.({key, val})
      new_value
    end,
    :maps.iterator(map)
  )
end
On Wed, 13 Jan 2021 23:55:17 -0500
Austin Ziegler <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> 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" <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 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
> > > > <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.
> > > >> 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 • 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.
> > 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
> > .
> >
> 
> 

-- 
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/6000506f.1c69fb81.6dc1c.59d9SMTPIN_ADDED_MISSING%40gmr-mx.google.com.

Reply via email to