Elixir 1.13.2 and the deprecation of Map.map/2

I don’t understand how Map.new/2 is a drop-in replacement of Map.map/2 since I get an error when I swap them. Maybe this is obvious but I don’t get it :thinking:

$ iex
Erlang/OTP 24 [erts-12.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Interactive Elixir (1.13.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> m=%{1=>1,2=>2}
%{1 => 1, 2 => 2}
iex(2)> Map.map(m, fn {_k,v} -> v + 10 end)
warning: Map.map/2 is deprecated. Use Map.new/2 instead
  iex:2

%{1 => 11, 2 => 12}
iex(3)> Map.new(m, fn {_k,v} -> v + 10 end)
** (ArgumentError) argument error
    (stdlib 3.17) :maps.from_list('\v\f')
    (elixir 1.13.2) lib/map.ex:220: Map.new/2

I think that’s a regression in Bring back filter/reject on Map and Keyword · elixir-lang/elixir@e987779 · GitHub

Which was then fixed in Optimize Map.new/2 · elixir-lang/elixir@31739ad · GitHub

Map.new will replace Enum.map on maps. For now I think you should still use Enum.map and into, if needed.


@kartheek is right. I didn’t look at the code carefully enough.

2 Likes

Typespec for Map.new is:

new(Enumerable.t(), (term() -> {key(), value()})) :: map()

it expects a function which takes a param and returns a tuple {key, value}

The function here does not return a tuple.

It should be changed to something like this

Map.new(m, fn {k,v} -> {k, v + 10} end)
5 Likes

ok, thanks :man_facepalming:

1 Like