Elixir, Weird Syntax, Is It Really ?

mpevec9

Milan Pevec

Posted on June 6, 2020

Elixir, Weird Syntax, Is It Really ?

Intro

So, Ive decided. To learn. Elixir. Ive started with watching some Youtube videos (Elixir Conference), 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), diagonally, but I wanted to jump directly into the sea with writting one example using Ecto library. And there I saw the subject of this blog - I saw the following lines of the code:

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":

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":

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 data structure for parameters of our function ? Lets try.

Our main.exs is gonna change to:

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:

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:

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

And now lets put it directly to our function call:

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:

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:

import Canvas

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

or if we break lines:

import Canvas

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

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

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.

馃挅 馃挭 馃檯 馃毄
mpevec9
Milan Pevec

Posted on June 6, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related