In BlogPost, Elixir

Last Updated: 11/11/2017 Saturday

How To Install Elixir

If you’re new to Elixir and have been wanting to learn it quickly, check out the Elixir Core Video course (now at special Beta launch pricing). In just 30 minutes a day, you can teach yourself the fundamentals of Elixir. Click on the image below to enroll today!

The Power of Proper Tooling

As I began to acquire more expertise and experience in programming, I realized that in some ways, 50% of the battle in getting started with learning a new technology stack is getting setup with the right tooling.

I still remember the first time I setup a shortcut for setting up git status. I added a shortcut with git st. One of my coworkers showed me a shortcut gs – even shorter! Holy cow, what a difference having not to type those last few characters makes!

And that’s the power of proper tooling

Proper tooling makes you more productive and makes programming more fun. I find having a proper environment manager to help you manage different releases of a language, makes it easy to test out different versions of the language. This especially holds true for an up and coming language like Elixir. So let’s dive into the tools!

Overview of The Tools

Let’s go over some tools you can use to manage your Elixir (and Erlang) installation. Since Elixir runs on top of Erlang, you’ll want a way to easily manage both Elixir and Erlang installations. Hopefully by the end of this, you’ll have everything setup and be ready to dive into the wonderful world of Elixir.

Kiex

If you’ve used a Ruby version manager like RVM or chruby, then you can think of kiex as being equivalent to that. Kiex is a handy little tool to let you easily install and/or switch between Elixir versions. And as Elixir is a fairly new language, it’s constantly being updated.

Kerl

Kerl is the tool that lets you easily switch out and build different Erlang versions. It’s a pretty handy tool to have since newer versions of Elixir keep using newer versions of Erlang. For example, due to some recent changes in the way Elixir handles debugging messages, Elixir 1.5 lets you take advantage of this functionality but only if you have Erlang 20 installed (at the time of this writing).

asdf

I would be somewhat remiss if I didn’t mention asdf, as it is a pretty handy tool that lets you install more than just Elixir. Asdf is “an extendable version manager” and it supports Erlang, Elixir, Ruby, and more languages. In my experience you end up with a .tool-versions file in your code repositories where you’re using the tool.

But that’s a minor thing in my opinion. Overall, if I hadn’t done kiex and kerl, I might have gone with asdf. The point is, “you do you”. Pick what is most comfortable to you.

Installing Elixir with Kiex and Kerl

I’m going to give you a step-by-step overview of how to install Elixir with kiex and kerl.

If you’re used to using Ruby in your day job, you’ve probably come to appreciate the Ruby ecosystem of tools to get setup and running – bundler and rvm (or chruby or rbenv depending on your preferences).

But I’m used to RVM and other environment managers – where is the RVM for Elixir?

It turns out there’s a few options for Elixir. As I stated before, I ended up choosing Kerl and Kiex. Here is how I installed it on my Ubuntu desktop and Mac OSX laptop.

Step 1 – Installing Kiex

Kiex is like RVM in that it allows you to switch between different Elixir versions and build them. Below is a set of instructions you enter at the command line.

Step 2 – Installing Kerl, Elixir and Erlang

Because Elixir runs on top of Erlang, you need a way to build and install Erlang/OTP instances.

Below is a set of instructions you enter at the command line.

You can activate this installation running the following command:

In .bashrc (or .zshrc if you use z shell), add the following:

Later on, you can leave the installation by typing: kerl_deactivate

You can delete a build with kerl delete build 20.0.

to .bashrc (or .zshrc or any other .rc file)

Troubleshooting

If you get a debug message such as:

Add the following to your shell’s config file (.bashrc/.zshrc/.cshrc):

Other useful commands

erl version will list the Erlang version, you will see something like: Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 5.8.3

Summary

As I said before, 50% of the battle in getting started with learning a new technology stack is getting setup with the right tooling. It’s more productive and more fun to get started the right way.

The tools are always changing in the programming landscape, so if you find a cool tool you like, I do hope you’ll share it with me so I can keep this guide updated for others as well as yourself!

Programming Terminology

Zen Masters and Adopting the Functional Mind

So let me tell you a story.1

Once, a long time ago, there was a wise Zen master. People from far and near would seek his counsel and ask for his wisdom. Many would come and ask him to teach them, enlighten them in the way of Zen. He seldom turned any away.
One day an important man, a man used to command and obedience came to visit the master. “I have come today to ask you to teach me about Zen. Open my mind to enlightenment.” The tone of the important man’s voice was one used to getting his own way.
The Zen master smiled and said that they should discuss the matter over a cup of tea. When the tea was served the master poured his visitor a cup. He poured and he poured and the tea rose to the rim and began to spill over the table and finally onto the robes of the wealthy man. Finally the visitor shouted, “Enough. You are spilling the tea all over. Can’t you see the cup is full?”
The master stopped pouring and smiled at his guest. “You are like this tea cup, so full that nothing more can be added. Come back to me when the cup is empty. Come back to me with an empty mind.”

Learning Functional Programming Meant I Had to Let Go of the Object Oriented Mind

In Elixir, there is no such thing as “objects”. There’s no such thing as “classes”. Most importantly, you’ll hear a phrase “data is immutable”.

This means that values in a certain memory location don’t change. Often, you will see something like:

This is referred to as “binding” the value 2 to v. If you then did v = 3, this simply points v to a memory location that contains the value 3. The memory location that contains the value 2 still exists. That’s why you refer to this operation as “rebinding the variable v to the value 3” instead of “assigning 3 to v” the way you do in object oriented languages.

From a programming standpoint, now both 2 and 3 are in memory until they are garbage collected.

How This Immutable Thing Relates to Elixir Processes and “Let It Crash”

If you hang around the Elixir community long enough, you’ll hear the phrase “let it crash”, meaning to let a process (containing data) just crash if an unexpected error happens. A process never has access to another process’s data (and hence state), and so you don’t have to worry that losing one process will affect behavior or data in another process. It’s a recipe for a more stable system.

In object-oriented languages (like Java), where data can be mutated across threads, one thread can be updating while another can be reading from a data store, and so you need to worry about “protecting” state during concurrent operations.

The beauty and implication of the “rebinding” of the variable v, is that you have a guarantee that your data in a memory location won’t change. Said another way, the “data is immutable”.

Object-Oriented vs Functional

As I said before, one thing that you should be aware of right off the bat is that you’re going to have to let go of your old notions of programming via object orientation. You’ll see what I mean by that as we look at more of the Elixir language. For now, let’s look at the first syntactical difference – the lack of classes.

Modules vs Classes

If you’re coming from the Ruby world or some other object-oriented paradigm like Java, you may be used to dealing with the concept of classes. In Elixir, there’s no such thing as a class. Instead Elixir gives you a module, which is a way to group functions together.

The other interesting implication of not having classes is that there’s no such thing as “an instance of a class”, or in this case “an instance of a module”. You always call functions with the following syntax of ModuleName.function_name(arg1, arg2, …).

Below is an example of a Calculator module with an add function.

In a working Elixir program, you might have the Calculator perform some work with the following code:

Functions: Input X, Receive Y

Now that you’ve gotten a taste of Elixir modules and functions, I want to introduce one more analogy to help you wrap your head around the concept of functional programming. If you’ve ever taken an algebra class, you might be used to hearing about functions such as “f of x” (denoted f(x) for short).

You might have seen things like y = f(x) = x + 2 which means f(x) (or y) is the result of adding 2 to every input x. And that’s simply how Elixir operates – you take some data, transform it via a function, and voila, you have a new result, or a new piece of data to operate on.

If you haven’t taken algebra before, then you can think of it as a magician putting something into a hat (say a feather), and then pulling something else out of it, like a rabbit. One thing went in, and another came out.

Goodbye Inheritance

If you’re used to Ruby, you might be used to seeing inherited classes like the Dog class.

There’s no such thing as inheritance in Elixir. You just have modules that contain functions to operate on data.

Immutability

The other sticking point about Elixir that makes it different from an object-oriented language like Ruby is that data is immutable. In fact, hang around in the Elixir community long enough, and you’ll hear the word “immutability” thrown around a lot.

I already gave an explanation above, so I won’t rehash it. But to give it to you in the simplest terms, “data is immutable” means we never change data in memory, we only make copies of the data and transform it as necessary. The practical implication of this is that we don’t hold state in variables.

How do you do state?

This of course begs the question, then “how do you do state”? We’ll look at that in upcoming sections. For now, it’s sufficient to say that Elixir lets you hold state via a process mechanism. And it gives you tools like GenServer to help you do it.

Summary

It might take a little while for you to “empty your cup”, but hopefully the upcoming quizzes and projects will help you wrap your head around Elixir and functional programming concepts.

The Enum Module: The Answer To Ruby’s Enumerable

Everyone Loves the Count

When I was a little boy, I used to watch Sesame Street. The show had this character called Count von Count, or simply, The Count.

His job on the show was to teach kids about simple mathematical concepts like counting. Watching him made counting and other mathematical concepts entertaining and fun to apply.

But then I grew up and discovered the Enumerable module…

As a self-taught web programmer, my first language was Ruby, via learning Ruby on Rails. One thing that was new to me was the the Enumerable module and its methods. As I got used to it, I found the Enumerable module quite beautiful as it enabled me to easily and elegantly operate on array collections. JavaScript has similar methods and I’d be willing to be other object-oriented languages do as well.

In fact, if type “enumerable” into Google, I get the definition “able to be counted by one-to-one correspondence with the set of all positive integers.”

In fact, Ruby’s Enumerable module does feel like it’s designed to operate on a list of integers (or other “objects”). It became such a part of my toolset what I was hoping Elixir had one…

Introducing Enum…

Fortunately, Jose Valim, the creator of Elixir, was formerly a Ruby language programmer. So I’m betting he too appreciated the Enumerable module. And hence, we have the Enum module in Elixir.

Like the Enumerable module in Ruby, Elixir also provides us with the Enum module to work with collections. Typically, you’ll find yourself operating on lists and maps.

Lists look a lot like arrays in Ruby, but we’ll stick with the Elixir way of calling them lists.

Useful Enum Module Methods

Now let’s go over some useful Enum module methods. These are methods I find myself using over and over again in real world applications.

Enum#at

Let’s suppose we have the following list of integers bound to m.

What happens if we wanted to get the second element? In Ruby, you might do something like m[1]. You’ll find if you try that in Elixir you’ll get an error. Instead, you can use the at method of the Enum module as follows.

Enum#reduce

If you’re used to Ruby’s inject operator, you’ve probably seen things like:

The reduce method of the Enum module operates much the same way. Like all things in Elixir the major syntacitcal difference is that you call it using the module name follwed by the method name as follows:

Note that just like in Ruby’s inject method, the Enum#reduce method has an accumulator to hold the results of your computations.

Enum#map

Like Ruby, Elixir also gives you a map operator.

In Ruby:

In Elixir:

Enum#filter

Ruby gives you a handy select method to “filter” elements you want from an array. Below we select all elements from the array for which the condition holds true.

The Enum#filter method operates much the same way.

Enum#reject

Ruby’s converse of the select method is the reject method.

Enum#all?

Ruby also has an all? method which is extremely similar to Elixir’s. Or perhaps I should say it’s the other way around.

In any case, the all? method returns true if all the elements meet the condition.

Hopefully by now you’re seeing a common pattern. There are parts of Elixir’s syntax that borrow beautifully from Ruby (or should I say shamelessly copy?)

Enum#any?

Ruby also has an any? method to check if any element in a collection meets a particular condition.

Elixir also has an any? method.

Enum#to_list with a range

Sometimes you want to generate a long list of numbers but you don’t want to type it all out. The solution is to pass a range into Enum’s to_list method and let it do the work for you.

Enum#count

Sometimes you just want to know the length of a list. The count method can easily do that for you.

Summary

Like Sesame Street’s, The Count, the Enum module makes learning fun. The Enum module gives you quite a few useful methods for operating on data. I encourage you to read the documentation and discover even more methods. An upcoming quiz will ask you to make use of Enum’s methods, so stay tuned!

The List Module

The Linked List Data Structure and the CSV Reporter

I did study Computer Science in university, and one thing they covered was the linked list data structure. In Ruby (and other object-oriented languages), you basically get these for free through arrays.

Instead of arrays, Elixir has a concept called “lists”. They look very much like arrays and behave much the same way. They are an Elixir version of linked lists.

Making a YouTube CSV Reporter

While building my first simple production application, I built an Elixir application that pulled down data from YouTube and turned it into a CSV (comma-separate value) report. It pulled down publicly available metrics and emailed them to a business unit that needed them for reporting purposes.

As I built this application, I found myself operating on lists of data in Elixir. In fact, I’d say all my real world application usage of Elixir involved Lists in some way. So it’s definitely worth familiarizing yourself with the List module in Elixir.

Useful List Module Methods

Like the Array module in Ruby, Elixir also provides us with a module to work with lists. Typically, you’ll find yourself operating on lists and maps.

Lists look a lot like arrays in Ruby, but we’ll stick with the Elixir way of calling them lists.

List.first

Here is the Ruby syntax for calling first on an array.

And here is the Elixir syntax for calling first on a list.

List.last

Here is the Ruby syntax for calling last on an array.

And here is the Elixir syntax for calling last on a list.

List.flatten

Ruby gives you a flatten method for arrays as follows.

And so does Elixir.

List.foldl

Off the top of my head, I don’t know of a Ruby equivalent for Elixir’s foldl method.

But the foldl method uses a function to reduce the list from the left. Below is a code snippet with an explanation of how the list is being folded.

List.insert_at

Elixir’s List#insert_at function is probably closest to Ruby’s Array#insert function.

Here is how you insert into an array at a particular index value. We insert the value 5 at index 1.

Here is the Elixir equivalent.

List.delete_at

When deleting an element out of a list in Elixir, you simply specify the index number at which you wish to delete the element.

++ and – –

You can add elements to a list in Elixir with the ++ operator and remove them with the – – operator.


[1, 2] ++ [-1, 5] # => [1, 2, -1, 5]

t = [1, 2, -1, 5] t – [1] # => [2, -1, 5]

Summary

Lists are one of the most common data structures used in day to day Elixir development in my experience. It’s worth knowing the methods in that module as you will be using them frequently.

The Map Module

The Dictionary

If you’ve ever used Webster’s Dictionary, you know you look up a word, say “aardvark”, and flip through the pages to locate the definition. If you think of “aardvark” as a key of sorts, and then its corresponding definition as a “value”, you’ll have an analogy to the dictionary abstract data type.

Basically, you use a key to access a value. The first important property of a dictionary are that the keys are hashabale and equally comparable, which is often why keys are letters or numbers. The second important property is that the entries appear in no particular order (which is a contrast to Webster’s Dictionary).2

The Ruby language has an implementation of the dictionary data type called a Hash. So do other object-oriented languages like Java.

But what about Elixir?

Elixir has an implementation called a map. In fact, when I was building a reporting tool that emailed comma-separated value text files, I used the Map module quite a bit. As you work with Elixir, you’ll likely find that you use the Map module quite a bit as you transform and iterate over your data.

So let’s dive in to some useful map methods.

Useful Map Module Methods

Besides lists, the other data structure you’ll encounter frequently in Elixir are maps. I have found myself using them in everything I do,

Map.get

So Map’s get method lets you fetch a value by key. It’s very similar to the fetch method for a hash in Ruby.


m = %{:b => 2, “c” => 3, :d => 4}
Map.get(m, :b)
#=> 2

Map.get(m, :c)
#=> nil

Map.get(m, “c”)
#=> 3

You’ll notice from the above code, you have to be very specific about which key you use to fetch a value.

Map.put

Map’s put method is for putting a value associated with a key in a map. It can be used for adding new key and value pairs or updating old ones.

Elixir’s built-in syntax for updating maps

One cool trick I’ve learned from reading this blog post is how to do updating one or more map key values using a special syntax

Map.has_key?

Similar to a Ruby hash, Elixir gives you the ability to check if a given key is in a map.

Map.keys

Using Map’s keys function, you can get a list of keys only. This is analagous to Ruby’s keys function for Hash.

Map.values

Using Map’s values function, you can get a list of values only.

Map.replace

Map’s replace is handy in that it will alter the value associated with a key, but only if that key exists.

Map.merge

Map’s merge is another handy data transformation function I often find myself using to merge 2 maps together.

Map.drop

Map’s drop is good for removing keys from the list.

Map.to_list

Interestingly enough, I recently found out you could convert maps to a list of tuples.


m = %{:b => 2, :c => 3}
t = Map.to_list(m)
#=> [b: 2, c: 3]

List.first t
#=> {:b, 2}

Map.update

I haven’t used Map’s update too much, but it’s pretty handy for updating key values in a map. In the below example, code I used an initial value of “-1”, which is what the value of “a” would have been if it had not already existed in the map. Instead, the value of a is set to “1 times 3”, which is 3.

A word on nested maps

One thing I found that was hard to deal with was when I wanted to drop keys out of nested maps. To that end, I built a hex package called nested_filter to handle this. It’s a bit complicated at this point, but someone was kind enough to review it and if you go through the commit history you can see how it evolved.

We’ll probably come back to this later when we discuss anonymous functions, but I wanted it to mention it now in case you wanted to take a look.

Summary

The Map module is something you’ll use over and over again. It’s something I used in my first Elixir application for CSV reports and it’s something I still use in my production applications today.

Footnotes

Katas 1 and 2

Now let’s do some quick practice to internalize the concepts.

When I was learning the Vim text editor, I used to be amazed watching skilled Vim users. It was a bit like watching skilled martial artists.

It’s amazing and yet also a little bit intimidating, especially if you’re new.

To get their advanced skills, martial artists often train through the use of exercises called katas.

So I’m calling these Elixir quizzes and exercises kata after those simple karate exercises designed to train the mind and muscle for specific applications.

Doing the Katas

The easiest way to jump in would be to start up an iex shell and start experimenting. You can also write an elixir script as well.

Kata 1: Transforming an Integer List

Generate a list of integers from 1 to 50 and transform them into a map where each integer is a key and its value is twice that of the key. So for example, you should end up with a map that looks something like:

%{1 => 2, 2 => 4} and so on…


# Input
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]

Output

# %{1 => 2, 2 => 4, 3 => 6, 4 => 8 # … etc.}

Kata 2: Transforming a List of Maps Into Success Tuples

Transform the following list of maps under the Input section to the structure in the Output section in the below coding sample.


# Input
list = [%{1 => 2}, %{2 => 4}, %{3 => 6}, %{4 => 8}, %{5 => 10}, %{6 => 12}, %{7 => 14}, %{8 => 16}, %{9 => 18}, %{10 => 20}]

Output

[ok: 2, ok: 4, ok: 6, ok: 8, ok: 10, ok: 12, ok: 14, ok: 16, ok: 18, ok: 20]
This one might be a bit tricky. The above output is equivalent to:

It’s a list of tuples.

Hints for Kata 2:

1) I used the Enum.reduce function, though you might be able to do it another way.

Conditionals in Elixir

Conditional Control Flow Structures

My Overreliance on Cond

When I first started with Elixir I tended to rely on conditionals much more than I would care to admit. This is because I wasn’t quite fluent with a concept called pattern matching, which is something we’ll talk about in upcoming course modules.

I tended to do things like:

Today I would cringe at that kind of code. A better improvement would have been to use a case statement (and an even better one would be the use of pattern matching). And that leads us to the topic of conditionals. We’re going to talk about cond, case, and if.

Cond

Coming from Ruby, cond reminds me of the if/elsif/end structure in Ruby. In other languages it’s equivalent to an if/else if type of control flow.

Its use case is to match on conditions. In the example below, you can see you hit the “catch all” true condition, which is like hitting the “else” portion of an if/else conditional flow in Ruby.

Case

In production ready code, I’ve seen the case conditional used quite a bit, especially when pattern matching against success and error tuples. Below is an example snippet in the context of a Phoenix controller. The hypothetical “DoSomething” module does something with the incoming params map and then the with_params method returns a success or error tuple.

From there, we let the phoenix controller decide what to render.

The underscore _ in the case statement acts as a catchall, much like the true in the cond statement.

If

The interesting thing to note about Elixir’s if statement is that unlike Ruby, there’s no concept of elsif. So you won’t run into a lot of nested if statements (hopefully) unlike in some of the Ruby startup code bases I’ve seen.

You can do nested if statements, but it’s ugly and I’ve never seen it any good codebase. So please do avoid it, although I will show it to you here for completeness sake.

Unless

Elixir’s unless statement follows the same pattern as its if statement.

Summary

As a general rule of thumb, a case statement is more idiomatic than cond, but cond has its uses. It’s rare to see if statements in Elixir, although it does happen.

Handy Keywords For Working With Modules and Anonymous Functions in Elixir

The 2 Hardest Problems in Computer Science

There are only two hard things in Computer Science: cache invalidation and naming things.
– Phil Karlton

So the quote from Phil Karlton I pulled from Martin Fowler’s website.3

And the longer I kept programming, the more I realized that Phil was right. Naming things – whether it be variables, classes, or files – is really hard. I can recall in my own object-oriented programming, how taxing it could be trying to name classes and methods in accordance with the problem domain I was looking at.

Unfortunately, functional programming with Elixir can’t solve this problem. However, there are tricks Elixir gives you to save you from typing your module names over and over.

When working with the Elixir frameworks such as Phoenix, you’ll find these tricks useful especially when dealing with the namespacing of modules.

In this section, we’re going to talk about handy keywords when working with Modules as well as Anonymous Functions in Elixir.

Alias and Import

Alias and import are two of the most common features of Elixir you’ll most likely be using when you first start using Elixir, especially if you’re using it in a web application (at least in my experience).

Alias

I think of the alias command as a shortcut to save you from typing. In actuality, you can do more with it.

For example, suppose you have the following module(s) defined.


defmodule Project.Calculator.Adder do
def add(a,b), do: a + b
def add(a, b, c), do: a + b + c
end
defmodule Project.Machine do
alias Project.Calculator.Adder

# we can call Adder.add thanks to alias

def add_two(a, b), do: Adder.add(a, b)
end
defmodule Project.Machine2 do
alias Project.Calculator.Adder, as: C
def add_two(a, b), do: C.add(a, b)
end

We could have also aliased Project.Calculator.Adder as something else entirely with the as option as shown in the Project.Machine2 module.

The other thing you can do is alias more than one module in the same line. In the below example, I am aliasing the Project.Calculator.Arithmetic modules and the Project.Calculator.Subtracter modules in one line.

Try the source code for yourself by copying and pasting it in the iex shell.

Import

I think of import as a way to easily use functions from other modules without having to type out any part of the module name (unlike alias).

Here’s how that would look with our Calculator example.

Interestingly enough, I recently learned that import has an only option to let you only import macros or functions. You can also specify specific functions that get called as well. You’ll notice the numbers 2 and 3 in the code above. This tells Elixir to only import the function that takes 2 arguments or 3 arguments, respectively.

You can see this in the commented line in the previous code block example with Project.Machine.

Module Attributes

If you’re used to constants in Ruby, you might be wondering what is the best way to handle those in Elixir. So far, I’ve found 2 good ways, one is through using private functions (defp my_function, do: "private_constant") and module attributes.

Let’s go back to our calculator example and see how we can use them.

There’s a bit to unpack from the above sample code (which you can paste into your iex shell and try out).

Summary

Naming things is still a hard problem whether you’re doing functional programming or object-oriented programming. Fortunately, Elixir does give you tools to at least save you some typing when you are constructing module namespaces and re-using module functionality.

Footnotes

A Word On Types

The First Thing I Do When Getting Started With a Programming Language

Every program I’ve ever written comes down to dealing with data in some way. One of the first things I do when learning a new programming language is to get a sense of the data types available to me. For example, when I was doing Ruby on Rails work, and wanted to create database columns with numbers, I wanted to know how the Rails commands that auto-generated database table creation commands mapped to a database’s data types.

It’s also important to understand whether you’re dealing with a statically-typed language like Java, which means you have to declare upfront what type of variable it is (e.g., int a = 2;, which means a holds an integer), or a dynamically typed language like Ruby where variables can hold any kind of data.

Like Ruby, Elixir is a dynamically typed language. Unlike Erlang, Elixir will allow you to rebind a value to a variable. That’s why you can do:

So now it’s time to take a look at the data types available to you in Elixir.

Integers and Floats

Elixir has integers and floats as its primary way of representing numbers. And it has the Integer and Float modules with functions to allow you to work with those types.

Arithmetic

One nice feature Ruby gives you is the “%” or modulus operator for finding the remainder of a division operation.

Elixir gives you this through the “rem” function.


rem(9, 3)
#=> 0

rem(6, 4)
#=> 2

Boolean

Elixir gives you true and false as boolean values. Interesting enough, they are equivalent to their respective atoms.


true == :true
#=> true

is_atom(true)
#=> true

false == :false
#=> false

Atoms

You’ve seen atom keys throughout this lesson in the various example map structures we’ve shown.

Elixir has a concept called atoms. An atom’s name is its value. If you’ve worked with the Ruby programming language, you’ll find they are analagous to Ruby symbols. If you’re coming from a language like Java or C++, I’m not sure there’s an equivalent analogy, so for clarity’s sake I’ll show a code example.

You can see in the above code example that :a and :b are both atom keys in a map.

Strings

Strings in Elixir are UTF-8 encoded and you use double quotes to represent them.

Note: single quotes denote character lists and mean something else entirely.

Lists

Lists are analogous to arrays in Ruby or other object-oriented languages like Java. We’ve seen them throughout the course in various examples.

Tuples

One interesting type that you don’t have an analogy for as a Ruby programmer is the tuple. You define a tuple with curly braces. Tuples can hold any kind of value and store data contiguously in memory.

What does this mean practically? It means you can use the Kernel#elem method to get a tuple element by its index is a fairly fast operation.

Summary

Ok, so now you’ve been given a crash course on the types available to you in Elixir. Coming up, we’ll be looking at comprehensions and some other concepts before we head into your first project.

Elixir’s Comprehensions (Not Loops)

The Misuse of Elixir’s Comprehensions

So having some minor experience with Java and other object-oriented languages, I was curious if Elixir had a “for loop”, “while loop” or some other kind of looping construct.

And when I found the “for” keyword in Elixir, I thought “finally”. And of course I tried to use it like a “for loop” in an object-oriented language where I stored a piece of stateful information in a variable and expected it to be available later….Oops. I think I was trying to implement a version of the Traveling Salesman Algorithm.

The Purpose of Comprehensions

If you recall the Enum module in Elixir, there were sets of operations that allowed you to loop over a list/collection, and transform the list into another one.

Comprehensions are simply another way of doing this. The Elixir documentation refers to comprehensions as “syntactic sugar” for such operations.

A Simple Example of a Comprehension

To get an idea of what comprehensions can do, let’s look at a simple example.

As a comparison, you could have done the above example with a map such as in the below example.

Multiple Generators

In the above example comprehension x <- [3, 4, 5] is referred to as a generator. You can have multiple generators in a comprehension.

You can see what happened. First, 3+1 and 3+2 were computed. Then 4+1 and 4+2 were computed. Finally, 5+1 and 5+2 were computed.

Extracting Data Using Pattern Matching

You can also use comprehensions in to transform a keyword list (list of tuples) into a different data structure, such as a list. If you look closely at the code below, you’ll notice you’re pattern matching.

Filtering in Comprehensions

If you recall from the article/video on Enum, there was a filter function that allowed you to select elements that met a certain condition. Comprehensions allow you to do this too. Look at the example below.

And with the above pattern matching and filtering mechanism provided to us by comprehensions, we select only the keys associated with odd values.

Into a Map

Let’s be honest. Sometimes you don’t want lists, you want a map. And you can have that with the handy :into option.

In actuality, you can apply :into to any structure in Elixir that implements what’s known as the Collectable protocol. We are going to touch on protocols in an upcoming section, so I will hold off on defining them for now. Suffice it to say, you can pass in a list, map, or string into the :into option.

Summary

So hopefully you’ve gotten a good overview of what you can do with comprehensions. And the next time you see the for keyword in an Elixir program, think “comprehension” not “for loop”.

Strings in Elixir

When IO.inspect Let Me Down With a Character List

So in other languages, sometimes you want to output the contents of an array to see what it contains. For example, in the Ruby programming language, if I have an array a = [8, 9, 10, 11], I can do the following.

Notice how I can see the array contains 8, 9, 10, and 11.

When I started with Elixir, I found I could more or less do the same thing with IO.inspect. But one day, I was let down with a surprise. I did the following.

WTF is going on?

But first, we need to talk about binaries

To answer that, we have to learn about binaries. A binary is simply a sequence of bytes in Elixir. And a byte is simply 8 bits. And in computer-ese, a bit is simply a 0 or 1.

Let’s see how to represent a binary with actual code

Below is a code block that shows you how to represent a binary.

Now, the double angled brackets (« ») defines a new bitstring. Each bitstring is composed of many segments, each of which has a type. There are 9 types of segments that can be used in bitstrings including integer, float, utf8, utf16, and utf32.

What does this have to do with strings again?

Strings are a subset of binaries. Specifically, strings are a valid UTF-8 sequence of bytes. How do you know if you have a valid string on your hands? Fortunately, Elixir’s String module gives you a way with the valid? method.

Single versus double quotes

The other thing you’ll notice when dealing with strings in Elixir is the double-quoted and single-quoted strings.

Properties of double-quoted strings.

Before we dive into what single-quoted strings are, let’s talk about what you can do with double-quoted strings in Elixir. Here are the two most common use cases.

Common Use Case 1: Variable Interpolation

In some of the production-grade Phoenix web applications I’ve been writing, I’ve found variable interpolations in strings quite handy. For example, if I want to embed a dynamic link URL that changes depending on what “category” it is, I might do something as shown in the below code block.

If you’re familiar with a dynamic object-oriented language like Ruby, then this style of interpolation might look quite familiar to you.

You can also think of variable interpolation as an alternative way to concatenate strings.

For example, this is the “regular” way to concatenate strings:

But you could also do it this way:

Common Use Case 2: Documentation

In Elixir modules, you’ll often see strings used to document modules. Below is an example from a hex package I wrote called nested_filter.

Single-quoted strings are character lists

Remember from the paragraphs above how inspecting a list of integers produced the following?

Each of those characters is a codepoint, or a character. Each codepoint is represented by what’s known as a code unit, which refers to the number of bits an encoding uses. Examples of encodings include UTF-8 (8 bit encoding) and UTF-16 (16 bit encoding).

So when Elixir prints out a character list like the above example, it really prints out the UTF-8 codepoints that the character list of integers represents.

How do you avoid printing out the character representations?

Before I tell you, let me show you a really cool trick. Boot up an “iex” prompt and type h Inspect.Opts.

You should see something like:


Inspect.Opts

Defines the Inspect.Opts used by the Inspect protocol.

The following fields are available:

• :structs - when false, structs are not formatted by the inspect
protocol, they are instead printed as maps, defaults to true.
• :binaries - when :as_strings all binaries will be printed as strings,
non-printable bytes will be escaped.
When :as_binaries all binaries will be printed in bit syntax.

• :charlists - when :as_charlists all lists will be printed as char
lists, non-printable elements will be escaped.
When :as_lists all lists will be printed as lists.

• :limit - limits the number of items that are printed for tuples,
bitstrings, maps, lists and any other collection of items. It does not
apply to strings nor charlists and defaults to 50.
• :printable_limit - limits the number of bytes that are printed for
strings and char lists. Defaults to 4096.
• :pretty - if set to true enables pretty printing, defaults to false.
• :width - defaults to 80 characters, used when pretty is true or when
printing to IO devices. Set to 0 to force each item to be printed on its
own line.
• :base - prints integers as :binary, :octal, :decimal, or :hex, defaults
to :decimal. When inspecting binaries any :base other than :decimal implies
binaries: :as_binaries.
• :safe - when false, failures while inspecting structs will be raised as
errors instead of being wrapped in the Inspect.Error exception. This is
useful when debugging failures and crashes for custom inspect
implementations
• :syntax_colors - when set to a keyword list of colors the output will
be colorized. The keys are types and the values are the colors to use for
each type. e.g. [number: :red, atom: :blue]. Types can include :number,
:atom, regex, :tuple, :map, :list, and :reset. Colors can be any
t:IO.ANSI.ansidata/0 as accepted by IO.ANSI.format/1.

Notice the “:as_lists” argument you can pass to the “:charlists” option. The following code example illustrates this:

When you pass in the “:as_lists” argument, you get back a list of integers from calling IO.inspect.

Note: the :as_lists option is for Elixir >= 1.5. According to this stackoverflow post4, with Elixir < 1.4, use pass “false” as an argument to the “:char_lists” option.

You previously saw this before in the discussion of double-quoted strings, but I’ll include the example below again for convenience.

Heredocs

Finally, no discussion of strings would be complete without at least mentioning Heredocs. Heredocs are multiline strings which are used to document code in Elixir (at least, that’s the way I’ve mostly seen them).

Case study: A Parsing Protocol

TBD – coming soon

Cool References

http://culttt.com/2016/03/21/working-strings-elixir/
https://medium.com/@harry_dev/elixir-for-rubyists-charlists-binarys-strings-iolists-eeacf38db999
https://www.bignerdranch.com/blog/elixir-and-io-lists-part-1-building-output-efficiently/
https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/

Recent Posts