Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Elixir: The Power of Erlang for Rubyists

Trevor Brown
September 01, 2014

Elixir: The Power of Erlang for Rubyists

An introduction to the Erlang VM and the Elixir programming language.

Trevor Brown

September 01, 2014
Tweet

More Decks by Trevor Brown

Other Decks in Programming

Transcript

  1. Erlang •  Designed for scalability
 and real-time systems •  Functional

    •  Simplifies concurrent programming •  Fault-Tolerant (“let it crash” error handling philosophy) •  Designed by Joe Armstrong in 1986 •  Legendary nine 9’s of uptime
  2. The Virtual Machine •  Each instance of the Erlang VM

    is called a node •  You can have one or more nodes on a physical machine •  You can spread nodes across multiple physical machines •  Nodes are one OS process, with one more more threads
  3. Erlang VM CPU   CPU   CPU   CPU  

    Thread   Thread   Thread   Thread   Virtual  Machine  Process   Process   Process   Process   Process   Process   Process  
  4. Processes •  Erlang processes are not OS processes •  Erlang

    VM distributes work of Erlang processes between the OS threads of the VM’s OS process •  Processes are concurrent •  There is no “main” process. Everything is a process and there are not special types of processes
  5. Processes •  Processes are independent of each other •  Processes

    cannot modify each other •  No data is shared between processes •  Processes can only interact with each other via message passing •  Processes are extremely lightweight •  Processes can be linked together, processes can also be monitored by other processes
  6. Processes are Actors •  Implements the actor model •  Processes

    encapsulate state •  Elixir’s processes are more object-oriented than objects in object-oriented languages
  7. Elixir •  Dynamic •  Functional •  Built on top of

    the Erlang VM •  Leverages the VM to build concurrent, distributed and fault-tolerant applications. •  Created in 2011 by José Valim •  First major release expect sometime in the next month
  8. Why use Elixir? •  All the benefits of Erlang • 

    Easily reuse Erlang libraries •  No additional performance costs •  Better tooling, which allows for greater productivity •  Better syntax •  Simplified metaprogramming
  9. What Elixir is Not “Elixir is like Ruby on the

    Erlang VM”
 •  Elixir is VERY different from Ruby, but the syntax is similar –  Functional vs OO –  Pattern Matching –  Recursion –  Immutable Data Structures
  10. What Elixir is Not “Elixir is like CoffeeScript for Erlang”

    •  Elixir provides better tooling, first-class docs, and easier metaprogramming than Erlang •  Additional data types
  11. Data Types •  All data is immutable •  Atoms, just

    like symbols in Ruby •  Booleans have been faked using the atoms ‘true’ and ‘false’ #  Atoms   :hello   #  Atoms  can  be  pattern  matched   :a  =  :a  
  12. Binaries and Numbers #  Binaries   <<97,98,99>>      

    #  Integers   12       #  Floats   23.5  
  13. #  Tuple   {:one,  :two,  :three}       #

     Tuples  that  are  stored  contiguously  in  memory   {1,2,3,4}       #  We  can  access  a  tuple  element  with  the  `elem`  function   elem({1,  2,  3},  0)  #=>  1       #  Tuples  can  be  pattern  matched   {:a,  second,  third}  =  {:a,  :b,  :c}   second  #=>  :b   third  #=>  :c       #  Tuple  length  matters  when  pattern  matching   {a,  b,  c}  =  {1,  2}   #=>  **  (MatchError)  no  match  of  right  hand  side  value:   {1,2}   Tuples
  14. Lists •  No array type, only linked lists. •  Each

    item in the list contains the value, along with a pointer to the next item in the list.
  15.   #  List   [1,2,3]       #  In

     Elixir,  just  like  in  Erlang,  the  `=`  denotes  pattern   #  matching  and  not  an  assignment.  It  is  a  "challenge"       #  We  can  access  the  head  and  tail  of  a  list  as  follows   [head|tail]  =  [1,2,3]   head  #=>  1   tail  #=>  [2,3]       #  Sometimes  pattern  matching  fails   [head|tail]  =  []   #=>  **  (MatchError)  no  match  of  right  hand  side  value:  []   Lists
  16. String(ish) Types •  No true string type •  Elixir represents

    strings as binaries underneath •  Lists can also be used to represent string data
  17.   #  Strings  and  char  lists   "string"  #  string

      'char  list'  #  char  list       #  Strings  are  all  encoded  in  UTF-­‐8:   "José"  #=>  "José"       #  `?a`  returns  the  ASCII  integer  for  the  letter   `a`   ?a  #=>  97       #  Strings  are  really  binaries,  and  char  lists   are  linked  lists.   <<?a,  ?b,  ?c>>  #=>  "abc"   [?a,  ?b,  ?c]      #=>  'abc'   Strings
  18. #  Maps   %{  one:  1,  two:  2,  three:  3

     }       #  HashDicts   [one:  1,  two:  2,  three:  3]       #  Keyword  Lists  allow  duplicate  values   [one:  1,  one:  "One",  two:  2]       #  Structs   defmodule  User  do      defstruct  username:  "",  email:  "",  real_name:  ""   end   More Data Types… •  Maps, HashDicts, Keyword Lists, and Structs
  19. Modules •  Code organization is done via modules and functions

    defmodule  Ping  do      @moduledoc  """      Sample  module      """          #  Add  functions  here   end    
  20. Functions •  In Ruby, functions/methods are identified by name, in

    Elixir they are identified by name and arity. def  add(0,  0)  do:  0   def  add(x,  y)  do:  x  +  y       def  add(x,  y,  z)  do      x  +  y  +  z   end  
  21. Pattern Matching #  In  Elixir,  just  like  in  Erlang,  the

     `=`  denotes   pattern  matching   :a  =  :a  #=>  :a   :a  =  :b  #=>  **  (MatchError)  no  match  of  right  hand   side  value:  :b       #  Atoms  can  be  used  in  pattern  matching   {:ok,  foo}  =  {:ok,  "foo  bar  baz"}   foo  #=>  “foo  bar  baz”       {:ok,  foo}  =  {:error,  :crashed}  #=>  **  (MatchError)  no   match  of  right  hand  side  value:  {:error,  :crashed}    
  22. Pattern Matching #  It's  common  practice  to  assign  a  value

     to  `_`   if  we  don't  need  it   {status,  _}  =  {:error,  :crashed}   status  #=>  :error     #  Patter  matching  a  list   [head|tail]  =  [1,2,3]   head  #=>  1   tail  #=>  [2,3]  
  23. Recursion •  There are no loops, only recursion #  Added

     all  the  items  in  the  list  together  to   compute  the  sum   def  sum_list([head  |  tail],  acc)  do      sum_list(tail,  acc  +  head)   end       def  sum_list([],  acc)  do      acc   End  
  24.     #  Implementation  of  reduce   def  reduce([],  value,

     _)  do      value   end       def  reduce([head|tail],  value,  fun)  do      reduce(tail,  fun.(head,  value),  fun)   end   Recursion
  25. Processes •  Message being sent to a process •  A

    process receiving messages #  `pid`  is  a  process   message  =  {:add,  1,  2}   send  pid,  message   #  Listen  for  messages   receive  do      {:add,  x,  y}  -­‐>          x  +  y      {:subtract,  x,  y}  -­‐>          x  -­‐  y      _  -­‐>          :error   end  
  26. Process Relationships •  Process spawn other processes
 •  Processes can

    be linked •  Processes can also monitor other processes #  Spawn  a  process   pid  =  spawn(worker_fun)   #  Link  the  process  calling   `link`  function  with  `pid`   process   link  pid   #  Monitor  `pid`  process  from   the  process  calling  the   `monitor`  function   monitor  pid  
  27. PingPong •  Two processes sending messages back and forth • 

    Resulted in an infinite loop <0.83.0>   <0.97.0>   Ping Pong {:ping,  <0.83.0>}   {:pong,  <0.97.0>}   <0.59.0>   Shell (Us)
  28. ProcessChain •  Thousands of processes arranged in a loop passing

    hundreds of messages around the loop. •  Demonstrates the efficiency of the Erlang VM’s message passing and lightweight nature of processes
  29. ProcessChain <0.97.0>   <0.38.0>   Chain Link Controller <0.83.0>  

    Chain Link <0.84.0>   Chain Link <0.77.0>   Chain Link <0.43.0>   Chain Link <0.26.0>   Shell (Us)
  30. Tennis •  Two processes maintaining their own state, sending messages

    back an forth, with processes randomly failing to send a response <0.83.0>   <0.97.0>   Player 1 Player 2 {:ping,  <0.83.0>}   {:ping,  <0.97.0>}   <0.59.0>   Shell (Us)
  31. Things I didn’t cover •  OTP - Open Telecom Platform

    •  Communication between nodes on different machines •  Metaprogramming •  Protocols •  The amazing pipe operator •  List comprehensions •  Much more!
  32. Go Try Out Elixir •  Install Erlang •  Install Elixir

    •  Instructions for installation are at http://elixir-lang.org/getting_started/1.html