Elixir, Weird Syntax, Is It Really ?
Tags: elixir
Published: 2020-06-06 21:00:33

## Intro
So, Ive decided. To learn. Elixir. Ive started with watching some Youtube videos ([Elixir Conference](https://www.youtube.com/channel/UC0l2QTnO1P2iph-86HHilMQ/featured)), just to get into it, to become attracted to it, cause time is a big constraint in my life, unfortunately, and without real attraction, there is no motivation.
## Syntax
For me coming from Java, Javascript world, doing some Ruby flirting, the syntax seemed strange. A bit. I was reading official docs ([Getting Started] (https://elixir-lang.org/getting-started/introduction.html)), diagonally, but I wanted to jump directly into the sea with writting one example using [Ecto](https://hexdocs.pm/ecto/Ecto.html) library. And there I saw the subject of this blog - I saw the following lines of the code:

```elixir
import Config

config :app1, Friends.Repo,
  database: "app1_repo",
  username: "user",
  password: "pass",
  hostname: "localhost"
```
Huh? That was my first reaction. Where is function, where are parentheses, brackets ? Weird syntax, is it really ? 

## Drill down sir
Seing that syntax was confusing. First I tough that I will skip "why?" and just use this. "Its just like this" approach. But after a day or two I've returned to this lines again.
Ive created my own example, slowly moving towards realisation that syntax is actually great and not weird at all!

### Step 1
I've created two elixir source files "canvas.exs":

```elixir
defmodule Canvas do
    def draw(title, color \\ "Red by default", shape \\ "Circle by default" ) do
        IO.puts("Draw a #{shape} with the color #{color}. Title is: #{title}.")
    end
end
```

and "main.exs":
```Elixir
Canvas.draw("Nice Canvas")
```

I've compiled canvas.exs and run main.exs with the expected output:
```
Draw a Circle by default with the color Red by default. Title is: Nice Canvas.
```
So far so good. As you can see, we created a module, function with default parameters and we print the final string. 
Now you might ask yourself, what has this to do with our subject of this blog ? You will see, we will get there.

### Step 2
What if we use the [keyword list](https://elixir-lang.org/getting-started/keywords-and-maps.html#keyword-lists) data structure for parameters of our function ? Lets try.

Our main.exs is gonna change to:

```Elixir
options = [{:color, "Green"}, {:shape, "Square"}]
Canvas.draw("Nice Canvas", options)
```

As you can see, keyword list is a key-value list, where keys are atoms. Neat.

Our canvas.exs is gonna change then to:

```Elixir
defmodule Canvas do
    def draw(title, options \\ []) do
        color = Keyword.get(options, :color, "Red by default")
        shape = Keyword.get(options, :shape, "Circle by default")
        IO.puts("Draw a #{shape} with the color #{color}. Title is: #{title}.")
    end
end
```
Elixir is offering Keyword module for manipulating keyword lists. Again very neat. But so far, very javascript-ish.

### Step 3
From now on, we will change only main.exs to bring it closer to our objective; Canvas module is going to stay the same.

Lets first change our keyword list. Because keys are atoms, we can use special syntax, where we use key values as following:

```Elixir
options = [color: "Green", shape: "Square"]
```

And now lets put it directly to our function call:

```Elixir
Canvas.draw("Nice Canvas", [color: "Green", shape: "Square"])
```

What if I tell you that there is more! Elixir official docs says the following:
**In general, when the keyword list is the last argument of a function, the square brackets are optional.**
That means we can do this:

```Elixir
Canvas.draw("Nice Canvas", color: "Green", shape: "Square")
```

Whaaat, thats so cool.

### Step 4
And now the final changes. As you probably know, there are two things more:
- for named functions parentheses are optional;
- if we use **Import** we don't need to prefix functions with module name;

So our final code change is:

```Elixir
import Canvas

draw "Nice Canvas", color: "Green", shape: "Square"
```

or if we break lines:

```Elixir
import Canvas

draw "Nice Canvas",
  color: "Green",
  shape: "Square"
```

Which is (almost) exactly the same as our initial Ecto code:

```elixir
import Config

config :app1, Friends.Repo,
  database: "app1_repo",
  username: "user",
  password: "pass",
  hostname: "localhost"
```

So now we can understand that above code is actually a call of the named function "config/3" ie. with three parameters:
- atom :app1
- alias Friends.Repo (which behind the scenes is an atom)
- keyword list used as last parameter, ie. function options

### Final toughts
So, is it weird ? No, I think is great, it's readable and has clarity. I like it.