Dip your toes into Elixir basics
with a walkthrough of a simple load testing tool
2 + 2 # 4
IO.puts "Oh, Hey!" # :ok, prints "Oh, Hey!"
events = [404, 500, :create, "dog"] # lists, dynamic typing
hd(events) # 404
tail(events) # [500, :create, "dog"
person = {:name, "Ben"} # 2-tuple
def fib(0) do: 0 # recursive fibonocci
def fib(1) do: 1 # pattern matching
def fib(n) do # multiple fun definitions
fib(n - 2) + fib(n - 1)
end
addTwo = fn a -> a + 2 end # anon function, 1st class
addTwo(2) # 4
Enum.map([1, 2, 3], addTwo) # [3, 4, 5]
iex(1)> pid = spawn fn -> IO.puts "I ... AM ... ALIVE!" end
I ... AM ... ALIVE! # printed from other process
#PID<0.85.0> # process identifier
iex(2)> Process.alive?(pid)
false # sadly, our process is dead :(
iex(3)> echoer = fn -> # define fun to receive msg
...(3)> receive do # blocking receive
...(3)> name -> IO.puts "Hi #{name}!"
...(3)> end
...(3)> end
iex(4)> pid2 = spawn echoer # create process, return pid
#PID<0.94.0>
iex(5)> Process.alive?(pid2) # alive, waiting for our msg
true
iex(6)> send(pid2,"Bob") # send async msg to other process
Hi Bob! # printed from other process
"Bob" # returned from send function
foo(0, 0) ->
boring; % Line terminator #1
foo(X, Y) ->
Y = math:add(X, Y), % Now we have 2
Z = Y rem 2,
case Z of
0 -> true; % Three for the win!
1 -> undefined % FOUR? nothing is really something
end.
But how does it do it?
200 + 200 # numbers
:dog # atoms (like symbols in Ruby)
name = "Ben" # binary strings
'Spruce' # list of ascii numbers ;)
person = {:name, name} # variable asigned a 2-tuple value
data = [1, 2, "dog"] # singly linked list
[100 | data] # [100, 1, 2, "dog"] # cheap
data ++ data # [1, 2, "dog", 1, 2, "dog"] # expensive
[id: 100, name: "Jane"] # keywordlist = [{:id, 100}, {:name, "Jane"}]
map = %{:a => 1, 2 => :b} # a map structure
map[:a] # returns 1
def print([]) do: :ok # pattern matching on function
def print([head | tail) do # pattern matching on value decomposition
IO.puts head
print(tail)
end # tail call optimized recursion
defmodule GreeterServer do
require Logger
use GenServer
def start_link(name) do # API METHOD, CALLED BY SUPERVISION TREE
GenServer.start_link(__MODULE__, name, [])
end
def init(my_name) do # initialize and return initial state
log("starting")
{:ok, my_name}
end
# async, use handle_call for simulated synchronous messages
def handle_cast(your_name, my_name) do
log("Hi #{your_name}, my name is #{my_name}")
{:noreply, my_name}
end
end
Stop checking Facebook and go to this URL
Please play around on the site for 60 seconds...
Does everyone have pruney fingers?