elixir
elixir copied to clipboard
Keyword.validate/2 has unpredictable behavior when accepted keys have duplicate entries
Elixir and Erlang/OTP versions
Erlang/OTP 27 [erts-15.2.1] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]
Elixir 1.18.2 (compiled with Erlang/OTP 27)
Operating system
macOS
Current behavior
iex(1)> Keyword.validate!([a: 3, b: 2], [:a, :b, a: 1])
[a: 1, b: 2, a: 3]
iex(2)> Keyword.validate!([b: 2, a: 3], [:a, :b, a: 1])
[a: 3, b: 2]
iex(3)> v(1)[:a]
1
iex(4)> v(2)[:a]
3
In the example above, :a is given twice as an expected key, one with no default and another with default = 1.
Depending on the order of the values passed in the first argument, it will assume the default instead of the passed value.
Expected behavior
Ideally, we should be erroring out when duplicate values are passed as accepted keys, because we don't accept duplicates in the first argument as well.
I can send a PR either way, just let me know the preferred solution!
This is tricky because checking for duplicates will make it more expensive, potentially enough to show up on hot code paths. So it will depend if we can have a reasonably efficient implementation. Please do send a PR giving it a try!
Closing in favor of the PR, even though we are not sure we can efficiently verify this, it depends on the implementation details.