Book Image

Learning Elixir

By : Kenny Ballou, Kenneth Ballou
Book Image

Learning Elixir

By: Kenny Ballou, Kenneth Ballou

Overview of this book

Elixir, based on Erlang’s virtual machine and ecosystem, makes it easier to achieve scalability, concurrency, fault tolerance, and high availability goals that are pursued by developers using any programming language or programming paradigm. Elixir is a modern programming language that utilizes the benefits offered by Erlang VM without really incorporating the complex syntaxes of Erlang. Learning to program using Elixir will teach many things that are very beneficial to programming as a craft, even if at the end of the day, the programmer isn't using Elixir. This book will teach you concepts and principles important to any complex, scalable, and resilient application. Mostly, applications are historically difficult to reason about, but using the concepts in this book, they will become easy and enjoyable. It will teach you the functional programing ropes, to enable them to create better and more scalable applications, and you will explore how Elixir can help you achieve new programming heights. You will also glean a firm understanding of basics of OTP and the available generic, provided functionality for creating resilient complex systems. Furthermore, you will learn the basics of metaprogramming: modifying and extending Elixir to suite your needs.
Table of Contents (16 chapters)
Learning Elixir
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Hello, World!


Now that Elixir is installed on your machine, let's fire up the interactive Elixir prompt. Open a shell/terminal emulator and run iex.

You should see the following text printed on the terminal:

$ iex
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

Before we continue, let's talk about some of the output of running iex. The line starting with "Erlang/OTP..." contains the Erlang emulator information tags. Each tag describes something about the underlying runtime VM. Here are some short explanations for each tag shown on my machine:

  • Erlang/OTP 17: This tells us the current version of Erlang.

  • [erts-6.4]: This is the version of the Erlang runtime system.

  • [source]: The Erlang emulator was compiled from source. This is typical if you or your package maintainer built Erlang from source (and didn't use the official precompiled binaries from Ericsson).

  • [64-bit]: This means the emulator is built to take full control of 64-bit memory addressing.

  • [smp:8:8]: This tells us how many CPU's and schedulers are available and online.

  • [async-threads:10]: This gives us the asynchronous threads available to the runtime.

  • [hipe]: This tells us that the Erlang emulator is compiled with the high performance extensions enabled.

  • [kernel-poll:false]: This informs us that the kernel polling is disabled.

For the majority of these, however, you don't necessarily need to concern yourself with until you get into system and performance tuning, which will be out of the scope of this book. There are also many more options that can be listed here, so you may want to, if you need, look at the Erlang BEAM emulator source (https://github.com/erlang/otp/blob/maint/erts/emulator/beam/erl_bif_info.c). A Stack Overflow question (http://stackoverflow.com/questions/1182025/what-do-the-erlang-emulator-info-statements-mean) has the same information as well, in a, perhaps, more accessible format.

Next, the line following the break tells us the version of Elixir installed, how to quit, and about a helpful command for getting, err, help.

Infamously, we can try typing, "Hello, World!", and we should see it echoed back to the screen:

iex(1)> "Hello, World!"
"Hello, World!"
iex(2)>

We can also do some basic arithmetic:

iex(2)> 40 + 2
42
iex(3)>

Best of all, we can get help documentation right in our shell by executing the following command:

iex(3)> h

                        IEx.Helpers

Welcome to Interactive Elixir. You are currently seeing the documentation
for the module IEx.Helpers which provides many helpers to make Elixir's
shell more joyful to work with.

This message was triggered by invoking the helper h(), usually referred to
as h/0 (since it expects 0 arguments).

There are many other helpers available:

  • c/2       — compiles a file at the given path
  • cd/1      — changes the current directory
  • clear/0   — clears the screen
  • flush/0   — flushes all messages sent to the shell
  • h/0       — prints this help message
  • h/1       — prints help for the given module, function or macro
  • l/1       — loads the given module's beam code and purges the current version
  • ls/0      — lists the contents of the current directory
  • ls/1      — lists the contents of the specified directory
  • pwd/0     — prints the current working directory
  • r/1       — recompiles and reloads the given module's source file
  • respawn/0 — respawns the current shell
  • s/1       — prints spec information
  • t/1       — prints type information
  • v/0       — prints the history of commands evaluated in the session
  • v/1       — retrieves the nth value from the history
  • import_file/1
              — evaluates the given file in the shell's context

Help for functions in this module can be consulted directly from the command line. As an example, try:

  h(c/2)

You can also retrieve the documentation for any module or function. Try these:

  h(Enum)
  h(Enum.reverse/1)

To discover all available functions for a module, type the module name followed by a dot, then press Tab to trigger autocomplete. For example:

  Enum.

To learn more about IEx as a whole, just type h(IEx):

iex(4)>

I'll let you try h(IEx).

To exit the interactive prompt, you can press Ctrl + C twice, or you can press Ctrl +G + Q + Enter.

As a quick aside, notice the numbers following the methods, for example, h/0. What is the number? The number stands for the arity or number of parameters the function expects. So, h/0 means the h function expects no parameters. This is often how we will see and talk about functions in Elixir (and in Erlang).

Using the IO.puts/2 function

Now we are going to try something else. We are going to continue with some more introductory examples and some code, modules, and functions we will use throughout the book.

Let's fire up our interactive Elixir prompt again:

$ iex
iex(1)>

This time, we are going to try "Hello, World!" with the IO.puts function:

iex(1)> IO.puts("Hello, World!")
Hello, World!
:ok
iex(2)>

Well, this is different. What happened? First of all, notice that "Hello, World!" is written to the screen without the quotes. Further, what is this :ok thing?

It just so happens that the IO.puts function is a function with side-effects; it writes its parameter's value to the screen. Since Elixir statements are all expressions, every statement must return a value. The value returned in this example, :ok, is an atom, and we will cover exactly what these are in the next chapter. For now, what is important is that this return value signifies to the caller, us, that the operation has been successful. It is very common for Elixir code that either succeeds or fails to return either the atom, :ok, or the atom, :error.

We can try this function with different data and should see similar results:

iex(2)> IO.puts(42)
42
:ok
iex(3)> IO.puts([])

:ok
iex(4)>

When we call IO.puts with 42, we get what we expect—the number 42 is written to the screen and we get the :ok return value. But what about the next example? It seems to return an empty string and :ok. What is going on here? Well, as it turns out, Elixir is interpreting the empty list as an empty list of characters. And certainly, we can print an empty list of characters as an empty string. We will discuss this more when we go over lists in the next chapter.

Using the inspect/2 function

Another function we will often use while developing and debugging Elixir code is the inspect/2 function. From the help, type h(inspect/2) in your iex:

def inspect(arg, opts \\ [])

Inspect the given argument according to the Inspect protocol.
The second argument is a keywords list with options to control inspection.

We will cover protocols more specifically in Chapter 9, Metaprogramming – Doing More with Less. For now, let's check the documentation of the Inspect protocol (http://elixir-lang.org/docs/v1.1/elixir/Inspect.html).

The Inspect protocol is responsible for converting any Elixir data structure into an algebra document. This document is then formatted, either in a pretty printing format or a regular one.

Essentially, the inspect/2 function allows us to peer into our data structures and see what's inside, in a readable format.

The inspect/2 function is a useful function for viewing the internal values or states of some data structures of our programs. These can also be used in print statement style debugging. To some degree, you may think of the inspect/2 function as a to string for most types. However, do not use this function for that purpose!