Beware though, only keyword lists are merged recursively:
config :foo, :config_key,
atom: :just_an_atom,
kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}],
map: %{list: ["hello", "config"]}
config :foo, :config_key,
new_atom: :this_is_new,
atom: :replaced_atom,
kwlist: [baz: 1, quux: 2],
map: %{}
$ iex -S mix
iex(1)> Application.get_env(:foo, :config_key)
[
new_atom: :this_is_new,
atom: :replaced_atom,
kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}, baz: 1, quux: 2],
map: %{}
]
If for some reason maps are used as config values, they won’t be merged; the latest value will simply override anything set before it:
config :foo, :config_key, %{
atom: :just_an_atom,
kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}],
map: %{list: ["hello", "config"]}
}
config :foo, :config_key, %{
new_atom: :this_is_new
}
$ iex -S mix
iex(1)> Application.get_env(:foo, :config_key)
%{new_atom: :this_is_new}
The same reasoning applies when overriding values one key at a time. So, using keywords, we can override a single key later like this
config :foo, :config_key,
atom: :just_an_atom,
kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}],
map: %{list: ["hello", "config"]}
config :foo, :config_key, kwlist: [new_key: nil]
$ iex -S mix
iex(1)> Application.get_env(:foo, :config_key)
[
atom: :just_an_atom,
map: %{list: ["hello", "config"]},
kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}, new_key: nil]
]
but if a map was used initially, it will be overriden:
config :foo, :config_key, %{
atom: :just_an_atom,
kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}],
map: %{list: ["hello", "config"]}
}
config :foo, :config_key, kwlist: [new_key: nil]
$ iex -S mix
iex(1)> Application.get_env(:foo, :config_key)
[kwlist: [new_key: nil]]