Now is the time where I finally stop talking about Elixir and start actually using it. We'll actually get to write some Elixir code today, although it's going to be really simple stuff. Let's start doing something!

IEx

The tool that we're going to be using for learning the language, at least initially, is IEx. This is an interactive programming shell for Elixir. In fact, I believe that "IEx" is an abbreviation of "Interactive Elixir". This environment will immediately evaluate Elixir statements and expressions and give you immediate feedback. Those of you familiar with Javascript or other languages with similar tools will know this as a REPL (Read-Evaluate-Print-Loop).

Not only is this is a fantastic tool for learning Elixir, it will allow you to try out Elixir code in an interactive environment before you use it in real code. You can load any Elixir code into the environment and try calling functions to see what happens. I hear it also has some limited debugging capability, but I imagine that it will be a while before I've progressed far enough to use that functionality.


Digression Time

If you want to see REPLs (or REPL-like environments) for a lot of other languages, go check out repl.it. It has all sorts of interactive environments for languages such as Javascript (browser), Javascript (Node.js), Python, Ruby, Clojure, C#, Java, and much more. It even has a C++ environment, although I'm not sure what that looks like. C++, along with most statically-typed languages, do not come with anything resembling a REPL, since they tend to be compiled and not interpreted.

Repl.it even has environments for some frameworks such as Ruby on Rails, React, Express, and Jest. You can write code, create code snippets, link to them, and share them. I've enjoyed using it. Unfortunately, Elixir is not yet in there. They've been steadily adding languages over the years (it started off with only Javascript), so I'm hoping Elixir will make it in at some point.


You can start up IEx by typing "iex" at the command line, and if the Elixir installation went well, you'll get an Elixir interactive environment.

chipmunk:lwmelixir Kevin$ iex
Erlang/OTP 21 [erts-10.0.8] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

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

You can type Elixir statements and expressions and watch them be evaluated, which we will do shortly. In order to exit this environment, you'll have to press Ctrl+C twice. It's a bit of an awkward way to exit, but that's the standard way to do it.

Variables

Let's start with a really trivial task: assigning values to variables. Fire up IEx and let's assign something to a variable.

iex> number = 10
10
iex> name = "Aethelstan"
"Aethelstan"

The first statement assigns the integer 10 to the variable number and the second statement assigns the string "Aethelstan" to the variable name. This looks pretty much like an assignment in a lot of other languages.

You'll notice that IEx echos the evaluation of the assignment statement, which is the same as the data that was assigned to a variable. We can also look at the data in a variable by just typing in the name.

iex> number
10
iex> age
** (CompileError) iex:4: undefined function age/0

iex>

When I typed in the variable number, IEx shows me the current value of number. When I typed in the name of a non-existent variable, age, an error is thrown. IEx displays the erro and returns to the iex prompt. In this case, Elixir couldn't find anything named age and apparently thought that I was attempting to reference a function.

In many statically-typed languages, a variable represents a piece of memory that always contains a value. When you assign a value, that memory overwritten with the value. In dynamically-typed languages (at least the ones I've used), the variable does not identify a particular piece of memory: it is just a symbol that be associated with any particular piece of data. Elixir is like that as well.

In fact, assigning a value to a variable is referred to as "binding" in Elixir. In the example above, the number variable is bound to the value 10. We can rebind it to another value, as shown below.

iex> number = 10
10
iex> number = 4
4

The number variable is changed so that it refers to a different piece of data. Since Elixir only has immutable data, this principle applies to every possible type of data. Symbols can be rebound, but the data itself is never modified.

Since Elixir is a dynamically-typed language, we don't have to associate the variable with any particular data type, like we do with statically-typed languages. We can bind the variable to any type of data.

iex> number = 5
5
iex> number = "five"
"five"

You can also enter value literals into IEx because those are valid expressions. IEx will evaluate the expression and show you the results.

iex> "This is a string value"
"This is a string value"

Echoing a literal admittedly not terribly useful, but it helps show how Elixir derives values from expressions.

Statements

A statement in Elixir does not end with any sort of terminating character, such as the semicolon (;) in the C-based languages. Javascript can have a terminating character, also the semicolon, but that is optional. In most cases (although there are a few exceptions), Javascript can figure out where statements end when you leave the semicolon off.

When Elixir reaches the end of the line, Elixir will know whether that statement is complete or if it should expect more on the next line. As far as I know of, there's no ambiguity in the language that would require a terminating character, although I have very little understanding at this point of how Elixir knows this. There's a set of grammar rules somewhere no doubt.

That said, it is possible enter multiple statements on the same line in Elixir, and a terminating character (a semicolon) is necessary in that particular case, but that's only to tell Elixir that you are using more than one statement and are not just making a syntactical mistake. I'm not a fan of multiple statements on the same line. I end to prefer each statement on its own line.

As you can see from this example, the value of the entire multi-statement line is evaluated to be the value of the last statement.

iex> number = 10 ; name = "Bob"
"Bob"

Variable assignment or binding is actually a very simple application of a much broader concept in Elixir called "pattern matching", where the language attempts to take what it sees on the right side of the = operator and match it to what it sees on the left side. Elixir sees something like x = 5, and thinks "Huh, I have a five on the right side and an x on the left side. Those two things must match each other, so I'll bind x to 5". It can get more involved than that. I only have a vague idea of what pattern matching involves at this point. I know it gets much more complex than that, so I 'm sure we'll be diving into detail about what this involves in a later post.

Garbage Collection

Like with other garbage collected languages (C# and Javascript both have garbage collection), memory is freed in Elixir when the data in memory is now longer being referred to by a variable or some data structure. As far as I know of, if you have a basic understanding of how most other languages perform garbage collection, you don't have to have any additional knowledge to understand how Elixir performs garbage collection. The concepts are pretty much the same.

File Types

Not all our code will be entered into IEx. Like any other language, we can write our code in source code files. There are two Elixir file extensions for source code.

  • .ex: .ex files are compiled into binary bytecode by the compiler, and are used for the development of most projects. A compile step is necessary for compiling these files
  • .exs: .exs files are script files that are not compiled, but interpreted at runtime. Elixir scripts tend to be used for scripting purposes, defining tests, or other small-scale coding efforts where we want to avoid a build process and we don't need the improved performance that compiling gives us.

I'm going to be using .exs files in most of my examples where I'm not typing things into IEx, but later on I'll likely be using .ex files when I'm working a real project with a build process. I have yet to learn how to do that.

Coding Convention

The convention for Elixir code is to use snake case, similar to Python. Snake case is all lower case letters separated by underscores. So you'll see things like my_variable_name for variables and do_something_useful for functions.

An identifier such as a variable or function that begins with an underscore "_" means that you should ignore it, as it's intended for some sort of internal use or just isn't used at all. I've seen a similar convention in Javascript code. I'm not sure under what circumstances you'd see identifiers like this, but if you do, you'll know why they start with an underscore in front.

It's an Elixir coding convention to use two-column indentation and to use spaces instead of tabs. So there shouldn't be any spaces vs tabs disputes in the Elixir world.

Data Types

You may notice that I haven't said much about data types at this point. There's a lot to say about them. We'll go over data types in more detail in the next post.