Andrey Deineko
Andrey Deineko

Reputation: 52357

In Elixir why can I not use different notations when creating a map?

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?

EDIT

OS: Ubuntu 15.4

Elixir: 1.1.1

Upvotes: 6

Views: 149

Answers (2)

Andrey Deineko
Andrey Deineko

Reputation: 52357

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 %{}.

Upvotes: 3

Hécate
Hécate

Reputation: 1035

Maybe for the sake of consistency? It's like walking with a flip-flop and a goth boot. You may look fancy, it's still extremely inconvenient.

Upvotes: 0

Related Questions