I am very new to elixir and cannot understand syntax.. I would appreciate for your advises

syntax

#1

defp new() do {

    north_c = [ ]
    north_d = [ ]
    north_h = [ ]
    north_s = [ ]

    south_c = [ ]
    south_d = [ ]
    south_h = [ ]
    south_s = [ ]

    east_c = [ ]
    east_d = [ ]
    east_h = [ ]
    east_s = [ ]

    west_c = [ ]
    west_d = [ ]
    west_h = [ ]
    west_s = [ ]

    north = [north_c, north_d, north_h, north_s]
    south = [south_c, south_d, south_h, south_s]
    east = [east_c, east_d, east_h, east_s]
    west = [west_c, west_d, west_h, west_s]

    game = [north, south, east, west]

}

end

Hello! I would like to create a function which will return “game” object.
I wrote the code above, but I am not sure if that approach makes sense.

Moreover, when I try to compile this,

it gives me the following error:
== Compilation error in file assign2.ex ==
** (SyntaxError) assign2.ex:19: syntax error before: north_d
(elixir) lib/kernel/parallel_compiler.ex:208: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
** (CompileError) compile error
(iex) lib/iex/helpers.ex:200: IEx.Helpers.c/2

I will really appreciate any explanation and help.

Thank you!


#2

You do not use {} to delimit blocks in Elixir, what you need to do is:

defp new() do
    north_c = [ ]
    north_d = [ ]
    north_h = [ ]
    north_s = [ ]

    south_c = [ ]
    south_d = [ ]
    south_h = [ ]
    south_s = [ ]

    east_c = [ ]
    east_d = [ ]
    east_h = [ ]
    east_s = [ ]

    west_c = [ ]
    west_d = [ ]
    west_h = [ ]
    west_s = [ ]

    north = [north_c, north_d, north_h, north_s]
    south = [south_c, south_d, south_h, south_s]
    east = [east_c, east_d, east_h, east_s]
    west = [west_c, west_d, west_h, west_s]

    [north, south, east, west]
end

#3

Welcome to the forum!

There are no objects in elixir only immutable values. And there are no statements, only expressions, i.e. expressions always evaluate to some value.

That function will only return a list of nested lists. I wonder if you were looking for something like:

defmodule Assign do
  def new do
    # values are immutable so they can be shared
    # without danger of mutation
    empty_core = %{c: [], d: [], h: [], s: []}

    %{
      north: empty_core,
      south: empty_core,
      east: empty_core,
      west: empty_core
    }
  end
end

iex(1)> c("assign.ex")
[Assign]
iex(2)> game = Assign.new()
%{
  east: %{c: [], d: [], h: [], s: []},
  north: %{c: [], d: [], h: [], s: []},
  south: %{c: [], d: [], h: [], s: []},
  west: %{c: [], d: [], h: [], s: []}
}
iex(3)> IO.puts("#{inspect(game)}")
%{east: %{c: [], d: [], h: [], s: []}, north: %{c: [], d: [], h: [], s: []}, south: %{c: [], d: [], h: [], s: []}, west: %{c: [], d: [], h: [], s: []}}
:ok
iex(4)> game = Kernel.update_in(game, [:west, :d], &([:ok|&1]))
%{
  east: %{c: [], d: [], h: [], s: []},
  north: %{c: [], d: [], h: [], s: []},
  south: %{c: [], d: [], h: [], s: []},
  west: %{c: [], d: [:ok], h: [], s: []}
}
iex(5)> 

Kernel.update_in/3
Kernel.inspect/2
IO.puts/2


#4

Welcome to the forum and Elixir, nice to have you.

On top of what has already been said, it looks like you are making the same mistake most people new to elixir (and more used to certain other languages): Lists look Arrays, because many other languages use the [] syntax for Arrays, but Elixir lists are linked lists, not Arrays.

In many cases you can just use them like you would use an Array, but this seems to be a perfect case for maps, the way peerreynders used them.

If you have any other questions, you might want to join the Elixir Slack workspace or Discord server - or of course just ask in the Forum again :smile:


#5

While not an the exact answer you’re looking for, as someone who came from imperative programming, and scope being defined by {…} I found going through this complete guide very helpful. Between that and a Derek Banas video, I’ve up and running witb OTP ever since. Ymmv, hth.