Kasun Vithanage
That easily
Joe Armstrong
This makes Erlang suitable for
Soft-Realtime Systems 😚
% module definition
-module(fact).
-export([fac/1]).
fac(0) -> 1;
fac(N) when N > 0, is_integer(N) -> N * fac(N-1).More from here
José was a RoR(Ruby on Rails) contributor.
He wanted to make it safe and performant 🚀
Instead, he ended up creating a new programming language 😬
So dont be like him, please 😰
No, I'm kidding...
José Valim
Elixir has a modern clean look, its like reading English 😎
Finally, you can use all cores of your VPS or whatever to run your dream app which scales to millions of users 😍
Of course, it's functional...but you don't need to learn Monads, Functors or do a PhD to understand code 🤓
Fortunately, it compiles to Erlang BEAM bytecodes, so you can access the Erlang ecosystem without any problem 🎉
More from here
:ok, :error
true, false, nil are special atomstrue or false1 == 1 is true1 == 3 is false{:ok, "1", 1.2} is a tupleadd.(1, 2)would give 3
add/2 means add has 2 argsadd = fn a, b -> a + b end
IO.puts(add.(1, 2))
Operators like +, -, / and * are used with numerical types.
div, rem can be used with integer division
++ and -- can be used to manipulate lists
iex(1)> [1, 2, 3] ++ [4, 5]
[1, 2, 3, 4, 5]
iex(2)> [1, 2, 3] -- [1]
[2, 3]
<> is used to concat strings
iex(1)> "hello" <> "world"
"helloworld"
Operators like and, or, not used with boolean values only
&&, ||, ! will work with any value. Everything except nil or false will be evaluated to truthy
= in Elixir is called Match Operator.
It can match left side and right side.
iex> x = 1
1
iex> 1 = x
1
iex> 1 = y # since y is not defined, we cant match this.
** (CompileError) iex:11: undefined function y/0 (there is no such import)
When you write x = 1, elixir will bind value 1 to variable x.
You can also rebind x to another value later as well.
iex> x = 1
1
iex> x = "wave"
"wave"
iex> x = "zync"
"zync"
iex> x
"zync"Match operator works on complex values as well
iex> {a, b, c} = {:hello, "world", 123}
{:hello, "world", 123}
iex> a
:hello
iex> b
"world"
iex> c
123
With Tuples
iex> list = [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
iex> [head | tail] = list
[1, 2, 3, 4, 5]
iex> head
1
iex> tail
[2, 3, 4, 5]
With Lists
If you want to match against an existing value without rebinding ^ (pin operator) is your friend
iex> x = 1
1
iex> ^x = 2
** (MatchError) no match of right hand side value: 2
iex> {a, ^x, b} = {1, 3, 1}
** (MatchError) no match of right hand side value: {1, 3, 1}
iex> {a, ^x, b} = {1, 1, 1}
{1, 1, 1}
Keyword List is a special list of two element tuples
iex> [{:hello, "world"}, {:age, 25}]
[hello: "world", age: 25]
iex> [hello: "world", age: 25]
[hello: "world", age: 25]There are 3 special charasteristics
This is really useful when passing options to functions
Maps are the "Go To" data structure in Elixir
Maps can have any value as keys
Maps also don't follow any ordering
iex> my_map = %{:hello => "world", "hi" => "elixir", 1 => 2}
%{1 => 2, :hello => "world", "hi" => "elixir"}
iex> my_map[:hello]
"world"
iex> my_map["hi"]
"elixir"
iex> my_map[1]
2Elixir doesn't have those built into the language, instead they are macros
iex> if String.length("hello") == 5 do
...> "its five"
...> else
...> "oh no"
...> end
"its five"
unless is the opposite of if
iex> unless String.length("hello") == 5 do
...> "oh no"
...> else
...> "its five"
...> end
"its five"Note that there is no return keyword.
if/unless works with boolean or nil only
case brings power of pattern matching into the play
iex> case {1, 2, 3} do
...> {1, x, 3} -> "matches x and binds it to 2"
...> _ -> "nothing matches any clause"
...> end
"matches x and binds it to 2"We can be more selective with guards
iex> case {1, 2, 3} do
...> {1, x, 3} when x > 0 -> "matches x and binds it to 2"
...> _ -> "nothing matches any clause"
...> end
"matches x and binds it to 2"You can apply multiple guards to same clause
Not only in case, multiple clauses can be used with functions too
iex> add = fn
...> x, y when is_number(x) and is_number(y) -> x + y
...> x, y when is_binary(x) and is_binary(y) -> x <> y
...> x, y -> "hmm not sure what to do"
...> end
#Function<13.126501267/2 in :erl_eval.expr/5>
iex> add.(100, 1)
101
iex> add.("hello", "elixir")
"helloelixir"
iex> add.("hi", 1)
"hmm not sure what to do"Note that is_number and is_binary are guards
You can also write custom guards 💂♂️
With anonymous functions, you need to maintain same aritey 🤓
This is similar to if/else if in other langs.
iex> cond do
...> 1 == 1 -> "its true, i knew it"
...> :a == false -> "who is the imposter"
...> end
"its true, i knew it"This is not widely used with elixir
But its there just in case 😏
Yes, even if, cond, case too
So we can write code like this 😎
iex> result = case {1, 2, 3} do
...> {1, x, 3} -> x * 10
...> {x, x, x} -> x * 3 # it matches when all elems are same
...> _ -> 100
...> end
20