Using the cons operator "|" with Keyword lists

Viewed 232

I'm trying to define a function where I specify part of a keyword list, and then match the remaining opts as the tail.

def my_func(foo: 22, bar: 42 | baz) do
  IO.inspect(baz)
end

my_func(foo: 22, bar: 42, another_arg: 11, even_more_args: 12)

and the idea is for baz to be a keyword list that contains [another_arg: 11, even_more_args: 12]

This doesn't compile, failing with the following error:

misplaced operator |/2

The | operator is typically used between brackets as the cons operator:

[head | tail]

However, I can pattern match a keyword list using the following:

def my_func([{:foo, 22}, {:bar, 42} | baz]) do
end

Since Keywords are semantic sugar for lists-of-tuples, it's not clear to me why the latter syntax works, but not the former. Is there some syntax I'm missing to be able to use | with keywords?

1 Answers

This happens because the keyword list syntax is valid only in context of a list, meaning that such syntax is invalid:

iex> test = foo: 22
** (SyntaxError) iex:8:8: syntax error before: foo

But this is valid:

iex> test = [foo: 22]
[foo: 22]
def my_func([[foo: 22], [bar: 42] | baz]) do
end

Of course the previous syntax is not suitable since it will make nested lists, however you cannot use keywords without a list, so you have to explicitly write it as a tuple.

What I would recommend is using the ++/2 operator:

def my_func([foo: 22, bar: 42] ++ rest) do
  IO.inspect(rest)
end
Related