There are 2 different syntaxes of defining a map:
map = %{:a => 1, :b => 2}
#=> %{a: 1, b: 2}
map = %{a: 1, b: 2}
#=> %{a: 1, b: '2}
Using both as follows while defining a map works:
map = %{:a => 1, b: 2}
#=> %{a: 1, b: 2}
But used in other order throws an error:
map = %{a: 1, :b => 2}
#=> ** (SyntaxError) iex:37: syntax error before: b
Why?
OS: Ubuntu 15.4
Elixir: 1.1.1
As per my issue on Github (which I actually should not have opened), this is not a bug.
First answer (which I did not really get):
It's not a bug, it's the same syntax sugar that is used for keywords on the last argument of a function.
foo(bar, baz: 0, boz: 1) #=> foo(bar, [baz: 0, boz: 1])
The map syntax is represented as function call in the AST:
iex(1)> quote do: foo(bar, baz: 0, boz: 1) {:foo, [], [{:bar, [], Elixir}, [baz: 0, boz: 1]]} iex(2)> quote do: %{baz: 0, boz: 1} {:%{}, [], [baz: 0, boz: 1]}
That's why the map keyword syntax only works for the last (or only) argument.
And the second answer, which sounded Ok in a sense that I think I got it:
Simple answer:
b: 2
is syntax sugar for[b: 2]
, but the sugar only works when it is at the end of a function call or "construct" such as%{}
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With