Mastering Elixir
eBook - ePub

Mastering Elixir

Build and scale concurrent, distributed, and fault-tolerant applications

André Albuquerque, Daniel Caixinha

Condividi libro
  1. 574 pagine
  2. English
  3. ePUB (disponibile sull'app)
  4. Disponibile su iOS e Android
eBook - ePub

Mastering Elixir

Build and scale concurrent, distributed, and fault-tolerant applications

André Albuquerque, Daniel Caixinha

Dettagli del libro
Anteprima del libro
Indice dei contenuti
Citazioni

Informazioni sul libro

Leverage the power of Elixir programming language to solve practical problems associated with scalability, concurrency, fault tolerance, and high availability.

Key Features

  • Enhance your Elixir programming skills using its powerful tools and abstractions
  • Discover how to develop a full-fledged file server
  • Understand how to use Phoenix to create a web interface for your application.

Book Description

Running concurrent, fault-tolerant applications that scale is a very demanding responsibility. After learning the abstractions that Elixir gives us, developers are able to build such applications with inconceivable low effort. There is a big gap between playing around with Elixir and running it in production, serving live requests. This book will help you fll this gap by going into detail on several aspects of how Elixir works and showing concrete examples of how to apply the concepts learned to a fully fledged application. In this book, you will learn how to build a rock-solid application, beginning by using Mix to create a new project. Then you will learn how the use of Erlang's OTP, along with the Elixir abstractions that run on top of it (such as GenServer and GenStage), that allow you to build applications that are easy to parallelize and distribute. You will also master supervisors (and supervision trees), and comprehend how they are the basis for building fault-tolerant applications. Then you will use Phoenix to create a web interface for your application. Upon fnishing implementation, you will learn how to take your application to the cloud, using Kubernetes to automatically deploy, scale, and manage it. Last, but not least, you will keep your peace of mind by learning how to thoroughly test and then monitor your application.

What you will learn

  • Use Elixir tools, including IEx and Mix
  • Find out how an Elixir project is structured and how to create umbrella applications
  • Discover the power of supervision trees, the basis for fault-tolerance
  • Create a Domain-Specifc Language (DSL) that abstracts complexity
  • Create a blazing-fast web interface for your application with Phoenix
  • Set up an automatic deployment process for the cloud
  • Monitor your application and be warned if anything unexpected happens

Who this book is for

Mastering Elixir is for you if you have experience in Elixir programming and want to take it to the next level. This Elixir book shows you how to build, deploy, and maintain robust applications, allowing you to go from tinkering with Elixir on side projects to using it in a live environment. However, no prior knowledge of Elixir is required to enjoy the complex topics covered in the book.

Domande frequenti

Come faccio ad annullare l'abbonamento?
È semplicissimo: basta accedere alla sezione Account nelle Impostazioni e cliccare su "Annulla abbonamento". Dopo la cancellazione, l'abbonamento rimarrà attivo per il periodo rimanente già pagato. Per maggiori informazioni, clicca qui
È possibile scaricare libri? Se sì, come?
Al momento è possibile scaricare tramite l'app tutti i nostri libri ePub mobile-friendly. Anche la maggior parte dei nostri PDF è scaricabile e stiamo lavorando per rendere disponibile quanto prima il download di tutti gli altri file. Per maggiori informazioni, clicca qui
Che differenza c'è tra i piani?
Entrambi i piani ti danno accesso illimitato alla libreria e a tutte le funzionalità di Perlego. Le uniche differenze sono il prezzo e il periodo di abbonamento: con il piano annuale risparmierai circa il 30% rispetto a 12 rate con quello mensile.
Cos'è Perlego?
Perlego è un servizio di abbonamento a testi accademici, che ti permette di accedere a un'intera libreria online a un prezzo inferiore rispetto a quello che pagheresti per acquistare un singolo libro al mese. Con oltre 1 milione di testi suddivisi in più di 1.000 categorie, troverai sicuramente ciò che fa per te! Per maggiori informazioni, clicca qui.
Perlego supporta la sintesi vocale?
Cerca l'icona Sintesi vocale nel prossimo libro che leggerai per verificare se è possibile riprodurre l'audio. Questo strumento permette di leggere il testo a voce alta, evidenziandolo man mano che la lettura procede. Puoi aumentare o diminuire la velocità della sintesi vocale, oppure sospendere la riproduzione. Per maggiori informazioni, clicca qui.
Mastering Elixir è disponibile online in formato PDF/ePub?
Sì, puoi accedere a Mastering Elixir di André Albuquerque, Daniel Caixinha in formato PDF e/o ePub, così come ad altri libri molto apprezzati nelle sezioni relative a Computer Science e Programming in Ruby. Scopri oltre 1 milione di libri disponibili nel nostro catalogo.

Informazioni

Anno
2018
ISBN
9781788472241
Edizione
1

Metaprogramming – Code That Writes Itself

We will now analyze how we can develop code that writes code for us, before being finally transformed into BEAM bytecode. This will let us extend Elixir, inject new code into existing modules, and even write a domain-specific language to simplify our media pipeline definitions.
What you will see through this chapter is only possible due to the incredible tools Elixir gives us to manipulate the abstract syntax tree just before it is turned into bytecode. Let's jump right into it!
In this chapter, we'll cover the following:
  • What is an abstract syntax tree and how to access it?
  • Using the special forms quote/2 and unquote/1
  • Macro hygiene and the caller and macro contexts
  • Applying use and its __using__/1 function
  • Using module attributes to collect information about the caller module
  • Creating a domain-specific language with macros

The abstract syntax tree

You may have already heard about Abstract Syntax Trees (ASTs) in other languages. As the name indicates, these are tree-like data structures that represent the code syntax. In Elixir, we call these representations quoted expressions.
If we try to obtain the quoted expression of simple expressions, such as single atoms, strings, integers or floats, lists or two element tuples, we'll see their quoted representation doesn't change when compared to their normal representation. These elements are called literals because we get the same value after quoting them. Take a look at the following code:
iex> quote do: :"Funky.Atom"
:"Funky.Atom"

iex> quote do: ["a", "b", "c", "z"]
["a", "b", "c", "z"]

iex> quote do: 1.88
1.88

iex> quote do: "really big string but still simple"
"really big string but still simple"

iex> {:elixir, :rocks} == quote do: {:elixir, :rocks}
true
The tree form of the quoted expressions is created by nesting three-element tuples and can be seen for complex snippets of code, which are composed by more than just Elixir literals:
iex> quoted_case = quote do
...> case 1 == 2 do
...> true -> "it seems 1 == 2 is true"
...> _ -> IO.puts "1 == 2 isn't true after all"
...> end
...> end
{:case, [],
[
{:==, [context: Elixir, import: Kernel], [1, 2]},
[
do: [
{:->, [], [[true], "it seems 1 == 2 is true"]},
{:->, [],
[
[{:_, [], Elixir}],
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
["1 == 2 isn't true after all"]}
]}
]
]
]}
In the preceding example, we are obtaining the quoted representation of a case statement. Each three-element tuple is usually composed by an atom (or another three-element tuple) for the function name, a list with metadata, and an arguments list. If the tuple represents a variable, the last element of the tuple will instead be an atom.
To evaluate a quoted expression, we can use the Code.eval_quoted/3 function. If we evaluate the previous quoted_case representation, we will get a two-element tuple, with the evaluation result and the value of the passed bindings after evaluation (the :ok atom is the return value of calling IO.puts/1):
iex> Code.eval_quoted quoted_case
1 == 2 isn't true after all
{:ok, []}
Our quoted case expression didn't have any variables, so we weren't able to observe how bindings work. Let's now see what bindings are for with the following quoted expression using a variable x:
iex> quoted_case_with_vars = quote do
...> case x == 2 do
...> true -> "it seems x == 2"
...> _ -> IO.puts "x == 2 isn't true after all"
...> end
...> end
{:case, [],
[
{:==, [context: Elixir, import: Kernel], [{:x, [], Elixir}, 2]},
[
do: [
{:->, [], [[true], "it seems x == 2"]},
{:->, [],
[
[{:_, [], Elixir}],
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
["x == 2 isn't true after all"]}
]}
]
]
]}
If you compare this quoted expression with the previous one, besides the minimal changes to the strings we're using, you can observe that the only change is, instead of having the 1 on the case equality comparison, we have the quoted representation of getting the value of x.
However, if we evaluate the quoted_case_with_vars expression with an explicit [x: 3] binding, it won't yield the expected result:
iex> Code.eval_quoted quoted_case_with_vars, [x: 3]
warning: variable "x" does not exist and is being expanded to "x()", please use parentheses to remove the ambiguity or change the variable name
nofile:1

** (CompileError) nofile:1: undefined function x/0
(stdlib) lists.erl:1354: :lists.mapfoldl/3
The behavior we're seeing here is deliberate, and the main reason for it is to spare ourselves from headaches further down the road; by default, these expressions are evaluated on a separate context and aren't able to access external variables (even if in this case we're passing x). If we want our expressions to access an outer value, like x, we have to wrap the x with a call to var!/1:
iex> quoted_case_with_external_vars = quote do
...> case var!(x) == 2 do
...> true -> "it seems x == 2"
...> _ -> IO.puts "x == 2 isn't true after all"
...> end
...> end
{:case, [],
[
{:==, [context: Elixir, import: Kernel],
[{:var!, [context: Elixir, import: Kernel], [{:x, [], Elixir}]}, 2]},
[
do: [
{:->, [], [[true], "it seems x == 2"]},
{:->, [],
[
[{:_, [], Elixir}],
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
["x == 2 isn't true after all"]}
]}
]
]
]}
This way, our case expression finally has access to the bindings we set on the Code.eval_quoted/2 call:
iex> Code.eval_quoted quoted_case_with_external_vars, [x: 2]
{"it seems x == 2", [x: 2]}
The previous examples highlighted a very important aspect of metaprogramming in Elixir: the final quoted expressions generated by us, are only able to access variables outside their context if we explicitly said so through var!/1.
This inability to access the outer context by default is called macro hygiene and is the safeguard that keeps things separate, without leaking into the context of the caller. The decision of accessing (and possibly changing) the outer context should be fully considered by the developer, and this separation by default rule helps keeps things sane.
After lo...

Indice dei contenuti