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!
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.
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.
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
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.
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.
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.
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.
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.
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.