Proposal: Map.replace/3 with a (map, key, fun) option

53 views
Skip to first unread message

Mackenzie Morgan

unread,
Dec 11, 2021, 4:24:00 PM12/11/21
to elixir-lang-core
Today's Advent of Code puzzle had a handful of us in the Elixir slack wishing for something that bridged the gap between Map.update/4, Map.update!/3, and Map.replace/3. 

Map.update/4 litters your map with extra keys you then have to find and filter out.
Map.update!/3 throws exceptions which can be especially undesirable in a pipeline.
Map.replace/3 requires you to pre-calculate the new value.

The goal would be "if this key exists in the map, update its value using this function." 

I wrote myself a little helper function (below) to wrap Map.replace/3, and I know someone else said they made a bunch of {key, nil} s and then had to filter them back out.

Anyway, Advent of Code probably isn't the only time it'd be helpful to have that syntactic sugar. Thoughts?

Mackenzie

  def replace_with(map, key, _) when not is_map_key(map, key), do: map
  def replace_with(map, key, f) do
    Map.replace(map, key, f.(map[key]))
  end

Andrea Leopardi

unread,
Dec 12, 2021, 2:15:08 AM12/12/21
to elixir-l...@googlegroups.com
I really like this and was thinking about this just yesterday, but was struggling to come up with a name. I was thinking of "update_if_existing" but "replace_with" is actually fantastic, follows our conventions, and sounds great. Awesome job!! If others on the core team agree, I think you could send out a PR for this 😊

On 11 Dec 2021, at 22:24, Mackenzie Morgan <mac...@gmail.com> wrote:

Today's Advent of Code puzzle had a handful of us in the Elixir slack wishing for something that bridged the gap between Map.update/4, Map.update!/3, and Map.replace/3. 
--
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/aace8ef8-3566-4637-afb5-56bfb2f3e626n%40googlegroups.com.

José Valim

unread,
Dec 12, 2021, 3:44:25 AM12/12/21
to elixir-lang-core
Thank you for the proposal!

I believe we actually discussed this a couple times, but we could never come up with a good name. My thoughts as of now:

* The terminology must definitely be "replace", because update is called even if the key is nil.

* However, we don't use the "_with" prefix much in the stdlib. However, we do have the "_lazy" suffix, which is about invoking a function. So far, the lazy suffix is "if such key does not exist, invoke this", but I think it would work on "replace_lazy" such as, "invoke this function only if the key exists".

Thoughts?

Andrea Leopardi

unread,
Dec 12, 2021, 7:48:22 AM12/12/21
to elixir-l...@googlegroups.com
I love lazy_ too. We use _with for Enum functions such as split_with, but in Map I prefer lazy_ too now that you brought it up!

On 12 Dec 2021, at 09:44, José Valim <jose....@dashbit.co> wrote:



José Valim

unread,
Dec 12, 2021, 8:52:59 AM12/12/21
to elixir-l...@googlegroups.com
A PR that adds replace_lazy to Keyword and Map is welcome!

Reply all
Reply to author
Forward
Message has been deleted
0 new messages