Mastering Elixir
eBook - ePub

Mastering Elixir

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

André Albuquerque, Daniel Caixinha

Compartir libro
  1. 574 páginas
  2. English
  3. ePUB (apto para móviles)
  4. Disponible en iOS y Android
eBook - ePub

Mastering Elixir

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

André Albuquerque, Daniel Caixinha

Detalles del libro
Vista previa del libro
Índice
Citas

Información del 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.

Preguntas frecuentes

¿Cómo cancelo mi suscripción?
Simplemente, dirígete a la sección ajustes de la cuenta y haz clic en «Cancelar suscripción». Así de sencillo. Después de cancelar tu suscripción, esta permanecerá activa el tiempo restante que hayas pagado. Obtén más información aquí.
¿Cómo descargo los libros?
Por el momento, todos nuestros libros ePub adaptables a dispositivos móviles se pueden descargar a través de la aplicación. La mayor parte de nuestros PDF también se puede descargar y ya estamos trabajando para que el resto también sea descargable. Obtén más información aquí.
¿En qué se diferencian los planes de precios?
Ambos planes te permiten acceder por completo a la biblioteca y a todas las funciones de Perlego. Las únicas diferencias son el precio y el período de suscripción: con el plan anual ahorrarás en torno a un 30 % en comparación con 12 meses de un plan mensual.
¿Qué es Perlego?
Somos un servicio de suscripción de libros de texto en línea que te permite acceder a toda una biblioteca en línea por menos de lo que cuesta un libro al mes. Con más de un millón de libros sobre más de 1000 categorías, ¡tenemos todo lo que necesitas! Obtén más información aquí.
¿Perlego ofrece la función de texto a voz?
Busca el símbolo de lectura en voz alta en tu próximo libro para ver si puedes escucharlo. La herramienta de lectura en voz alta lee el texto en voz alta por ti, resaltando el texto a medida que se lee. Puedes pausarla, acelerarla y ralentizarla. Obtén más información aquí.
¿Es Mastering Elixir un PDF/ePUB en línea?
Sí, puedes acceder a Mastering Elixir de André Albuquerque, Daniel Caixinha en formato PDF o ePUB, así como a otros libros populares de Computer Science y Programming in Ruby. Tenemos más de un millón de libros disponibles en nuestro catálogo para que explores.

Información

Año
2018
ISBN
9781788472241
Edición
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...

Índice