Sequential Elixir

Modules

A module is a collection of functions, somewhat like a namespace. Every Elixir function must be defined inside a module.

(Juric 2024, 23)

  defmodule A do
    defmodule B do
      ...
    end
    ...
  end

Module Attributes

defmodule Circle do @pi 3.14159

def area(r), do: r*r*@pi def circumference(r), do: 2*r*@pi end

Type Specs

Typespecs provide a way to compensate for the lack of a static type system. This can be useful in conjunction with the Dializer tool to perform static analysis of your programs. (Juric 2024, 34)

Functions

A function must always be a part of a module. Function names follow the same conventions as variables: they start with a lowercase letter or underscore character and are followed by a combination of alphanumerics and underscores.

(Juric 2024, 25)

  defmodule Mod do
    def func(a, b) do
      ...
      a + b
    end

    # If your function's body consists of a single expression, you can use the "do" notation
    def func2(a, b), do: a + b

    # You can also use defp to make the function private
    defp func3(a, b), do: a + b
  end

Arity

Arity describes the number of arguments a function receives. A function is uniquely identified by its containing module, name, and arity.

(Juric 2024, 29)

Numbers

Atoms

Tuples

Lists

Maps

A map is a key-value store, where keys and values can be any term. Maps have dual usage in Elixir. They’re used to power dynamically sized key-value structures, but they’re also used to manage simple records—a couple of well-defined named fields bundled together.

(Juric 2024, 46)

Binaries and Bitstrings

Strings

Higher-Level Types

The aforementioned built-in types are inherited from the Erlang world. After all, Elixir code runs on BEAM, so its type system is heavily influenced by the Erlang foundations. But on top of these basic types, Elixir provides some higher-level abstractions. The ones most frequently used are Range, Keyword, MapSet, Date, Time, NaiveDateTime, and DateTime.

IO Lists

Macros

Macros are one of the most important features Elixir brings to the table that are unavailable in plain Erlang. They make it possible to perform powerful code transformations at compile time, thus reducing boilerplate and providing elegant, mini-DSL expressions.

(…)

A macro consists of Elixir code that can change the semantics of the input code. A macro is always called at compile time; it receives the parsed representation of the input Elixir code, and it has the opportunity to return an alternative version of that code.

(Juric 2024, 62)

References:

Juric, Saša. 2024. Elixir in Action. Simon and Schuster.