DEV Community

Milan Pevec
Milan Pevec

Posted on

2 1

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.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more