Elixir from the ground up

Your first Elixir

What Elixir is, how a program says something, and the values it prints: text, whole numbers and decimal fractions.

Part 1 of 12

Beginner14 min readBack to Courses

Small ideas, used everywhere

Elixir has a small vocabulary and one strong rule: data is never changed in place. A function takes values and gives back new ones. That rule sits behind almost everything in this course, and it is why an Elixir program is easy to follow — no function you call can quietly alter something you are holding. It is not a restriction bolted on top; it is why two pieces of code can work on the same value without coordinating, and why a function can be tested with a value you already have.

The language runs on the same machinery as Erlang, a runtime built for systems that must keep working. None of that is needed to start. A file here is a list of instructions that run from the top down, and each Run comes back in about a second with whatever the program printed. The runtime starts the file, evaluates it, and stops; nothing is kept between runs, so each Run begins from the same definitions.

One honest limit of this page: there is nowhere for a program to read input from, so every lesson prints its answers instead of asking for them. The copy of Elixir here is 1.9.4, an older release — the few places where that matters are pointed out as they come up.

Saying something

IO.puts prints a line of output. IO.write prints without the line break, so the next thing carries on on the same line. IO.inspect prints a value in its raw form — quotes round text, brackets round a list — and hands the value straight back to you, which makes it the tool to reach for while working something out. Because the value comes back, an inspect can sit in the middle of an expression without changing what the expression produces.

A comment starts with a hash sign and runs to the end of the line. There is no semicolon to end a statement; a new line ends the thought.

Text with a hole in it

A string in double quotes may hold a piece of code in braces, and whatever that code works out is pasted into the text: "Hello, #{name}!". That is how an Elixir program builds a sentence — not by gluing parts together with plus signs. The braces can hold any expression, including a function call, and the result is converted to text for you.

Arithmetic looks the way you expect, with one rule worth knowing on day one: dividing with the slash always gives a decimal fraction, so 10 / 4 is 2.5. When you want whole-number division, ask for it by name with div. rem is its partner: it answers what is left over, so div(10, 4) is 2 and rem(10, 4) is 2, and together they give both parts of the division.

Printing, and text with a hole in it

IO.puts("Hello, Elixir!")

# IO.write leaves the cursor where it is.
IO.write("one ")
IO.write("two")
IO.puts("")

# IO.inspect shows the raw value, quotes and all.
IO.inspect("a string")
IO.inspect([1, 2, 3])

name = "Ada"
IO.puts("Hello, #{name}!")
IO.puts("two plus two is #{2 + 2}")

# Two integers divide to an integer.
IO.puts(10 / 4)
IO.puts(div(10, 4))
IO.puts(2 * 8)

Run it, then make it yours

Press Run and read the output line by line. Then change the name, add a line that prints a sum of your own, and print a string with a value pasted inside it.

Output
Click "Run" to execute your code

When output surprises you, print the value with IO.inspect instead of IO.puts. It shows the value rather than the friendly form: text keeps its quotes, a list keeps its brackets, and a decimal fraction stays a decimal fraction.

What a script actually does

A .exs file is a script: the runtime reads it from top to bottom and evaluates each expression as it arrives. An expression is anything that produces a value — 2 + 3 produces 5, and IO.puts("hi") produces :ok — and a name is bound to the value on its right. Nothing runs until the line above it has finished, so the output appears in the order you wrote the lines.

That is also why an error tells you where it happened. The script stops at the first expression it cannot evaluate, and the lines below never run. Read the message from the top: the first line names the file and the line number, and the rest explains what the runtime expected.

Three habits from other languages will bite you here: + adds numbers rather than joining text (use <>), single quotes make an older kind of text rather than a string, and 10 / 4 is 2.5 rather than 2. When the output stops early, read the first error before changing anything.

Try these next

  • Change the greeting to your own name and print a second line with your favourite number.
  • Print a price with IO.puts and again with IO.inspect, and note the difference in quotes.
  • Work out how many minutes are in three days and print the answer inside a sentence.

A tiny profile card

Run it and read the card. Then change the number of days to 400, add a line for a price with a decimal point, and print a sentence that uses every value on the card.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

What is the difference between IO.puts and IO.write?