I just upgrade OTP to 20.0 and elixir to 1.5.0-rc.1, I got warnings on usage of filter_map. Why is it deprecated?
Changelog for 1.5 says:
[Enum] Deprecate Enum.filter_map/3 in favor of Enum.filter/2 + Enum.map/2 or for-comprehensions
Yes, ‘filter+map’ or ‘for’ works, but I want to know the reason behind it.
I think the reason was the fact that it was an outlier. The only “fused” function.
Can someone help a rookie (me) understand the
[…] or for comprehensions
component of this deprecation message?
Parsing the English can be odd, but they’re these things, covered in the Guide https://elixir-lang.org/getting-started/comprehensions.html
for comprehensions consist of generators and filters, though the filters seem to be less widely known
Here is an example of using comprehension in lieu of
# filter even numbers filter_fn = fn n -> rem(n, 2) == 0 end # double map_fn = fn n -> n * 2 end some_enum = 1..20 # filter_map version Enum.filter_map(some_enum, filter_fn, map_fn) # comprehension version for n <- some_enum, filter_fn.(n), do: map_fn.(n)
map_join and the rest of the “fused” function?
Most of them are useful as a way to avoid walking a long list twice.
If you fear multi walks, then use the appropriate
Enum functions is just a legacy implementation? They don’t give us anything extra, they just help us avoid some extra code for some common use-cases?
reduce are considered base-most enumeration functions.
flat_map is the base-most that always returns another enumeration, and
reduce is the base-most that returns anything.
filter_map is pretty duplicative as I always use
[1, 2, 3] |> Enum.map(&(&1+3)) |> Enum.reject(&(&1==4)) # => [5, 6]
[1, 2, 3] |> Enum.flat_map(fn n -> case n+3 do 4 ->  n -> [n] end end) # => [5, 6]
Hello from the future. The commit log doesn’t mention why it was deprecated, but whatyouhide, a core team member, explained a bit on this issue:
Elixir deprecated the usage of
Enum.filter_map/3because it was counterintuitive and the same could be achieved with
Stream, or with a
And also José Valim in the mailing list:
I would use comprehensions:
for item <- 1, 2, 3, rem(item, 2) == 0, do: item * 2
There is no reason for Enum.filter_map or Enum.map_filter to exist besides backwards compatibility.