ELIXIR TUTORIAL
BASIC TYPES
Interactive Elixir (iex)
Type iex in the command line to enter the shell for Erlang /OTP environment.
FOUR TYPES
Atoms
Strings
Tuples
Lists
Maps
Elixir have two file types;
.exs: are intended for scripting and they stay in memory when run or executed.
.ex: are compiled to byte code and written to disk in a beam file.
ATOMS
It is a constant where its name is a value. Atoms are memory efficient.
Example:
C:\Users\essie>iex
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :firstname
:firstname
iex(2)> :"this is also atom"
:"this is also atom"
iex(3)> IO.puts(:"this is also atom")
this is also atom
:ok
iex(4)>
Atoms have returning values:
{:ok, content}
{:error, reason}
Atoms have Boolean
:true
:false
Example:
Inspect the Boolean true and false.
iex(7)> i false
Term
false
Data type
Atom
Reference modules
Atom
iex(4)> i true
Term
true
Data type
Atom
Reference modules
Atom
STRINGS
Format “sting_name”
Example:
iex(1)> euro = "#"
"#"
iex(2)> byte_size(euro)
iex(3)> String.length(euro)
iex(4)> name = "Hello, "
"Hello, "
iex(5)> hello = "Nana"
"Nana"
iex(6)> name <> hello
"Hello, Nana"
<>: concatenation
Example:
iex(7)> handle = "nana_yaw"
"nana_yaw"
iex(8)> "My tweeter handle is @#{handle}. Feel free to send a message."
"My tweeter handle is @nana_yaw. Feel free to send a message."
TUPLES
An ordered collection used for storing a peace of data, is use for two, three or four values.
Format: {“items”, ”items”}
Example:
iex(1)> book={"Programming Book", "Dave", 25.00}
{"Programming Book", "Dave", 25.0}
iex(2)> elem(book, 2)
25.0
iex(3)> put_elem(book, 2, 49.00)
{"Programming Book", "Dave", 49.0}
iex(4)> book
{"Programming Book", "Dave", 25.0}
LISTS
Lists is used for storing much more data
Elixir list is Single-Linked List
Format: [listitem, “listitem2”]
Example:
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> first_list = [1,2,3]
[1, 2, 3]
iex(2)> second_list = [:ok, 1, "test", first_list]
[:ok, 1, "test", [1, 2, 3]]
iex(3)> hd(first_list)
1
iex(4)> tl(first_list)
[2, 3]
iex(5)> third_list = [1 | [2,3]]
[1, 2, 3]
iex(6)> fourth_list = [1 | [2 | [3 | []]]]
[1, 2, 3]
iex(7)> [:ok | first_list]
[:ok, 1, 2, 3]
iex(8)> [a,b,c] = first_list
[1, 2, 3]
iex(9)> a
iex(10)> b
iex(11)> c
iex(12)> [head | tail ] = first_list
[1, 2, 3]
iex(13)> head
iex(14)> tail
[2, 3]
iex(15)> options = [{:is_active, false}, {:notify_user, true}, {:created_if_not_exists, true}]
[is_active: false, notify_user: true, created_if_not_exists: true]
iex(16)> options[:notify_user]
true
IMMUTABILITY
In elixir, data is immutable, meaning that if the data is created, it cannot change.
Example:
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> languages = ["Java", "PHP", "C"]
["Java", "PHP", "C"]
iex(2)> List.insert_at(languages, 0, "C++")
["C++", "Java", "PHP", "C"]
IMMUTABILITY BENEFITS
1. It provides concurrency of immutable data
2. It reuses memory
MAPS
Are collections of key value pairs.
Format: %{key => {“mapitem”}}
Similarities of lists and maps are collections of items that have a key and a value.
Differences
MAPS: the key does not have to an atom; it can be any type. It only allows one instance of each key.
MAPS are more efficient that Lists.
Keyword Lists don’t have that constraints
Example
iex(1)> my_map = %{1 => {"Nana", "Yaw"}, 2 => {"Mark", "Annafi"}}
%{1 => {"Nana", "Yaw"}, 2 => {"Mark", "Annafi"}}
iex(2)> other_map = %{:names => ["Nana Yaw", "Mark Annafi"], "gender"=> "male"}
%{:names => ["Nana Yaw", "Mark Annafi"], "gender" => "male"}
iex(3)> another_map = %{{:ok, 1} => true, {:ok, 2} =>false}
%{{:ok, 1} => true, {:ok, 2} => false}
iex(4)> other_map["gender"]
"male"
iex(5)> other_map.names
["Nana Yaw", "Mark Annafi"]
iex(6)> %{:names => names_lists} = other_map
%{:names => ["Nana Yaw", "Mark Annafi"], "gender" => "male"}
iex(7)> names_lists
["Nana Yaw", "Mark Annafi"]
MODULES AND FUNCTIONS
MODULES
Modules have 3 purpose;
They serve to annotate the module, often with information to be used by the user or
the VM.
They work as constants.
They work as a temporary module storage to be used during compilation.
Example:
Coding the .exs file;
defmodule ModulePlaygroup do
def say_hello do
IO.puts "Hello World Elixir"
end
end
Compile in terminal
C:\Users\essie\Desktop>iex "module_playgroup.exs"
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> ModulePlaygroup.say_hello
Hello World
:ok
iex(2)> r(ModulePlaygroup)
warning: redefining module ModulePlaygroup (current version defined in memory)
module_playgroup.exs:1
{:reloaded, ModulePlaygroup, [ModulePlaygroup]}
iex(3)> ModulePlaygroup.say_hello
Hello World Elixir
:ok
MODULES DIRECTIVES
1. IMPORT: Include module functions. Includes/Excludes specific functions from specific modules
Example:
Coding the .exs file;
defmodule ModulePlaygroup do
import IO, only: [puts: 1]
import Kernel, except: [inspect: 1]
def say_hello do
inspect "Hello World Elixir"
end
def inspect(param1) do
puts "Starting Output"
puts param1
puts "Ending output"
end
end
Compile in terminal
iex(2)> r(ModulePlaygroup)
warning: redefining module ModulePlaygroup (current version defined in memory)
module_playgroup.exs:1
{:reloaded, ModulePlaygroup, [ModulePlaygroup]}
iex(3)> ModulePlaygroup.say_hello
Starting Output
Hello World Elixir
Ending output
:ok
2. ALIAS: Reduce typing module names. Renaming modules in your modules
Example:
Coding the .exs file;
defmodule ModulePlaygroup do
import IO, only: [puts: 1]
import Kernel, except: [inspect: 1]
alias ModulePlaygroup.Misc.Util.Math, as: MyMath
def say_hello do
inspect "Hello World Elixir"
end
def inspect(param1) do
puts "Starting Output"
puts param1
puts "Ending output"
end
def print_sum do
MyMath.add(1,2)
end
end
defmodule ModulePlaygroup.Misc.Util.Math do
def add(a,b) do
a+b
end
end
Compile in Terminal
iex "module_playgroup.exs"
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> import_file("misc_util_maths.exs")
{:module, ModulePlaygroup.Misc.Util.Math,
<<70, 79, 82, 49, 0, 0, 3, 200, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 109,
0, 0, 0, 9, 37, 69, 108, 105, 120, 105, 114, 46, 77, 111, 100, 117, 108, 101,
80, 108, 97, 121, 103, 114, 111, 117, 112, ...>>, {:add, 2}}
iex(2)> ModulePlaygroup.print_sum
iex(3)> r(ModulePlaygroup)
warning: redefining module ModulePlaygroup (current version defined in memory)
module_playgroup.exs:1
{:reloaded, ModulePlaygroup, [ModulePlaygroup]}
iex(4)> ModulePlaygroup.print_sum
3
3. REQUIRE: Allows using macros in your module that will depend upon.
Example:
Coding the .exs file
defmodule ModulePlaygroup do
import IO, only: [puts: 1]
import Kernel, except: [inspect: 1]
alias ModulePlaygroup.Misc.Util.Math, as: MyMath
require Integer
def say_hello do
inspect "Hello World Elixir"
end
def inspect(param1) do
puts "Starting Output"
puts param1
puts "Ending output"
end
def print_sum do
MyMath.add(1,2)
end
def is_even(num) do
puts "Is #{num} even? #{Integer.is_even(num)}"
end
end
defmodule ModulePlaygroup.Misc.Util.Math do
def add(a,b) do
a+b
end
end
Compile in Terminal
iex(5)> r(ModulePlaygroup)
warning: redefining module ModulePlaygroup (current version defined in memory)
module_playgroup.exs:1
{:reloaded, ModulePlaygroup, [ModulePlaygroup]}
iex(6)> ModulePlaygroup.is_even(1)
Is 1 even? false
:ok
iex(7)> ModulePlaygroup.is_even(2)
Is 2 even? true
:ok
iex(8)> ModulePlaygroup.is_even(4)
Is 4 even? true
:ok
iex(9)>