iger

Learning Elixir - Day 1

Started learning Elixir and i wanted to use this as sort of notes to make sure i understand the topic that i’m learning.

Elixir is a dynamically typed (just like javascript) functional programming language where the typecheck happens only at runtime.

You simply define a variable like this:

Important

Numbers aren’t always floating point numbers like in javascript

variableA = 1
variableB = 2
count = 0
# you can reassign a variable to a different type
count = false
count = "heh"

defmodule is used to define a “module” - similar to a class in OOP

def is used to define a public function

defp is used to define a private function

The value of the last expression in a function is always implicitly returned

Functions can be written in one line:

defp private_subtract(x, y), do: x - y

It is common to use PascalCase to define module names, and unlike javascript, variable and function names should use snake_case.

Elixir has a Kernel module which is automatically imported, this includes basic arithmetic operations.

Arity of functions

The term is used to define how many arguments a function accepts:

# add/3 because this function has three arguments, thus an arity of 3
def add(x, y, z) do
  x + y + z
end

Anonymous functions

Think of anonymous function in Elixir like arrow function in javascript, example:

# you define them using the reserved keyword `fn`, `->` instead of `do`
add_one = fn num ->
  num + 1
end

# then you invoke like this
add_one.(1)
# => 2

Confusingly, this function above can be rewritten like this:

add_one = &(&1 + 1)

add_one.(1)
# => 2

They call this the “capture” operator, or &/1.

Important

Anonymous functions need to be invoked using the dot operator (./2) before the parentheses; named functions do not.

//2 always returns a float. Use div/2 and rem/2 (the remainder function) for integer division and remainders.

These functions are from the Kernel module, as mentioned above.

Bit manipulation

Not gonna lie i’m a bit excited about this - never really had the opportunity to use bitwise operations in javascript since it’s use cases are really niche (maybe in Elixir too)

Seems to be the case - Elixir has a Bitwise module that comes with bitwise functions


Side quest

While doing the exercise from Exercism, i found community solutions which solve the tasks using the short hand capture notation and noticed that the person uses then(secret_function1) to pipe the value to the next function instead of secret_function.():

add5 = secret_add(5)

10 |> add5.() # add5.(10)  => 15
10 |> then(add5) # then(10, add5) => add5.(10) => 15

then/2 is from the Kernel module and is mostly used with the pipe operator (|>) to inline an anonymous function, like this:

user |> then(fn u -> {u.id, u.name} end)

Or when the value from the pipe needs to be placed as a second argument:

5 |> then(&Enum.at([1, 2, 3, 4, 5, 6], &1))

Why the dot (when calling anonymous functions)?

Also i went on another rabbit hole trying to figure out why they invoke named and anonymous functions differently. This is pretty unusual coming from javascript so i decided to find the truth.

Then i stumbled upon this article which actually answers my question and to summarize in my own words, basically boils down to whether variables and functions are stored in a single namespace or different namespaces (for Elixir to know whether it’s calling an anon function stored in a variable or a named function).

Similarly in Erlang, the difference is not by using the “dot” when calling the anon function, but functions are defined with lowercase and variables start with an uppercase - so there is no way those two would clash.

If you’re interested in reading more, check out this paper


Booleans

When writing a function that returns a boolean value, it is common to use the ? suffix, similarly for variables that store boolean values:

def either_true?(a?, b?) do
  a? or b?
end

Even when using the variable and calling the function, you’d still need to use the ? suffix - if variable is defined with ?, then it needs to stay, if not, then ? can be omitted.

&&/2, ||/2, and !/1 operators can also be used instead of and/2, or/2, and not/1, respectively.

To be continued …