`Map.get/3` to return default value for `nil` value

170 views
Skip to first unread message

Nganga Mburu

unread,
Jun 22, 2022, 4:25:26 AM6/22/22
to elixir-lang-core
I've found myself and seen others expecting to receive the default value from `Map.get/3` when the value is `nil`.

An example is:
    `Map.get(%{name: nil}, :name, "John")` 
    
     Expected it to return "John" but it returns `nil`

My thinking is since the default value is for the key then when the key value is `nil` we should be able to get the default value.

The change in code could be as below:
     ```
     def get(map, key, default \\ nil) do
        case map do
           %{^key => value} when is_nil(value) ->
               default

           %{^key => value} ->
                value

           %{} ->
               default

           other ->
               :erlang.error({:badmap, other}, [map, key, default])
        end
     end
     ```

Andrey Yugai

unread,
Jun 22, 2022, 4:32:29 AM6/22/22
to elixir-l...@googlegroups.com
For this behavior I think you'd be better of using `map[key] || default_value`, or even `Map.get(map, key) || default_value`. Docs for `Map.get/3` are pretty clear about when it returns default value.







-------- Original Message --------
--
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/9d31c830-8005-4a76-a1f9-dbea2d841ea4n%40googlegroups.com.

Nganga Mburu

unread,
Jun 22, 2022, 4:37:55 AM6/22/22
to elixir-l...@googlegroups.com
We've used `map[key] || default_value`, or even `Map.get(map, key) || default_value` before but I felt this being handled my `Map.get/3` would be better.

`Map.get(map, key, default_value)` looks better than `Map.get(map, key) || default_value`


Andrey Yugai

unread,
Jun 22, 2022, 4:50:52 AM6/22/22
to elixir-l...@googlegroups.com
It indeed looks nicer, but that would be a breaking change, and maybe more importantly, subduing two different cases to one behavior. Sure, in your case you don't need to differentiate between an empty map and nil-instantiated map, but somebody else does. Perhaps you could change the upstream code to send you only nil key stripped maps or only fully instantied maps (e. g. structs).







-------- Original Message --------
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAFVCX%3D0KfetF09s9ofC4KTT-JCNv9eiKm42%2B4E--qFr29GJgkQ%40mail.gmail.com.

Austin Ziegler

unread,
Jun 22, 2022, 8:22:50 AM6/22/22
to elixir-l...@googlegroups.com

On Jun 22, 2022, at 04:37, Nganga Mburu <mburun...@gmail.com> wrote:


We've used `map[key] || default_value`, or even `Map.get(map, key) || default_value` before but I felt this being handled my `Map.get/3` would be better.

`Map.get(map, key, default_value)` looks better than `Map.get(map, key) || default_value`

This assumes that `nil` isn’t a valid value. For your use-case it may be. For other cases, it may be a valid and important value.

I know for a fact that this would break some production code we run and be a surprising result for us because it would not behave the way we expect for anything else, including JavaScript Map.get.

-a

Ben Wilson

unread,
Jun 23, 2022, 9:54:47 AM6/23/22
to elixir-lang-core
> `Map.get(map, key, default_value)` looks better than `Map.get(map, key) || default_value`

This isn't a matter of looks, these have straight up different functionality. You can't change this sort of thing in the language at this point in its lifecycle. Plus, you'd be forcing everyone who's doing that first thing to change to the far uglier multiline:

```
case Map.fetch(map, key) do
  {:ok, value} -> value
  _ -> default_value
end
```

Nganga Mburu

unread,
Jun 23, 2022, 10:04:36 AM6/23/22
to elixir-l...@googlegroups.com
Thanks a lot all for the responses. I get how this would break things considering `Map.get/3` is foundational to many other code bases. So we can consider this as better handled as it's currently done.

Thank you again.

--
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.
Reply all
Reply to author
Forward
0 new messages