About how from C # I moved to Elixir / Phoenix

Once I had to change jobs. Before that, I only worked with languages ​​like Python, C ++, C #, and a couple of similar ones. And now I had to start working with a functional language. First impressions were "yes what a garbage?". However, I managed to quickly adapt. Next, I will talk about the main points that I had to get used to or which I had to understand in order to start writing quickly and adequately.

1. Pattern matching

This is one of the main features of the language. But to fully understand it, until you begin to really write in the language is a little difficult. The first thing I read about matching patterns is that thanks to this thing, you can simply extract data from structures and associate them with variables. But in fact, everything is somewhat more complicated. Pattern matching works almost everywhere in a given language. I will give three examples illustrating the main applications that I use almost constantly.

Example 1. By definition:

{tuple_item_1, tuple_item_2} = tuple 

- breaks the 2-element tuple into two variables, which can then be used.

[head_item | tail_list] = list 

- splits the list into the first item in the list and the list without the first item.

Example 2. Matching in case:

case get_elem(struct) do
  {:ok, elem} -> …
  {:error, reason} -> …

The get_elem (struct) function returns a tuple, and the case allows you to immediately extract data and select a further sequence of actions.

Example3. Feature Mapping:

def function_1(params, :ok) do
def function_1(params, :error) do
def function_1(params, _) do

Here, in essence, the same function takes two parameters. Pattern matching allows you to choose which function to perform.

A little bit about the pattern matching work. Comparison is always top-down. In this example, when calling function_1 from two parameters, it will first check that the second parameter is equal to : ok . If the first check fails, the error will check for : error . And if not again, then we will in any case enter the third variant of the method. The underscore means "any data", and also the fact that the incoming data does not interest us, that is, we will not use them. If function_1 (params, _)first on the list, the program would always select it, and the other two methods would never work. If the desired pattern is not found, an exception will be displayed.

2. Pipeline

These are constructions of the following form:

|> func_1()
|> func_2(param_2)

At first glance it seems some kind of garbage. But it is worth remembering that Elixir is a functional language. And in a functional language it is quite normal to do the computation of a function of a function, without intermediate variables. Pipeline is just a convenient entry. The language itself asks for clarity to start the pipeline with a variable or value.

The example above can be rewritten as follows:

func_2(func_1(param_1), param_2)

In other words, the pipeline redirects the result of the calculation of the previous function to the next function by the first argument.

3. Lack of cycles There are no cycles

in the Elixir. This fact caused the greatest shock to me, and it is the most difficult to understand. Next comes my opinion and vision, which may not coincide with reality and theory.

The roots of this fact are in the functional programming paradigm, one of the provisions of which states that the result of the program is the work of a function that can call other functions and the program does not assume the storage of intermediate states. The cycles, in turn, are intended to repeatedly change the state external to the cycle.

Replacing the cycles are 2 things - recursion and library methods of working with enumerable elements of the language.

A little more about the little things.

1. In Elixir there are no classes, but there are contexts. Essentially, contexts in some way replace classes. The closest description of the context is the eyes of the b-sharper: contexts are a cross between the class and the namespace in Sharpe, and the context is much closer to the namespace.

2. Atoms. In Elixir there is such a thing as an atom. An atom is essentially something like a “tag.” The easiest way to treat them as a special line. In the examples of this article, there were already two atoms :: ok,: error . Thanks to atoms, it is much easier to perform pattern matching, and complex logical constructs. In essence, these are constants whose value is their name. An atom always has a ":" in front of the name.

3. How to read method headers correctly. In Elixir, it is customary to designate methods as follows (this is often seen in the documentation): & function / 2 . It is read as a method with the name “function” and arity 2. Arity is the number of arguments taken.

What helped me to join the language.

First, this is the reference book on the android “Elixir Tutorial”. It is good in that it briefly covers the main points of the language and its syntax, and it can be read on the bus. Minus: it is in English, so not everyone is suitable.

Secondly, the book "Introduction to Elixir" by Senloren S., Eisenberg D ... This book shows the techniques of working with the language and explain them. Easy to read and allows you to significantly improve your work with the language. Also it can be found in Russian.

Thirdly, the official online documentation. It is made conveniently and allows you to quickly find the necessary sections / methods, with a detailed description and examples.

That's all.

List of materials:

1. Elixir Tutorial

2. Senloren S., Eisenberg D. Introduction to Elixir. Introduction to functional programming. - O'Reilly, 2017.

3. Official documentation.

Also popular now: