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. Elixir: The Power of
    Erlang for Rubyists
    Trevor Brown

    View Slide

  2. Trevor Brown
    Sarasota, Fl

    Ruby, JavaScript,
    Erlang, and Elixir

    Erlang developer at Voalte

    View Slide

  3. What is Erlang?

    View Slide

  4. 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

    View Slide

  5. Processes and the
    Erlang VM

    View Slide

  6. 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

    View Slide

  7. Erlang VM
    CPU   CPU   CPU   CPU  
    Thread   Thread   Thread   Thread  
    Virtual  Machine  Process  
    Process  
    Process   Process   Process  
    Process   Process  

    View Slide

  8. Processes
    <0.81.0>

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

  11. Processes are Actors
    •  Implements the actor model
    •  Processes encapsulate state
    •  Elixir’s processes are more object-oriented
    than objects in object-oriented languages

    View Slide

  12. Processes
    Processes communicate via message passing
    <0.44.0>  
    <0.83.0>  
    <0.74.0>  
    <0.76.0>  

    View Slide

  13. What is Elixir?

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. What Elixir is Not

    View Slide

  17. 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

    View Slide

  18. 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

    View Slide

  19. Elixir Basics

    View Slide

  20. 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  

    View Slide

  21. Binaries and Numbers
    #  Binaries  
    <<97,98,99>>  
       
    #  Integers  
    12  
       
    #  Floats  
    23.5  

    View Slide

  22. Tuples
    •  Ordered collection of elements with a fixed size.
    •  Often used in pattern matching

    View Slide

  23. #  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

    View Slide

  24. 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.

    View Slide

  25.  
    #  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

    View Slide

  26. String(ish) Types
    •  No true string type
    •  Elixir represents strings as binaries underneath
    •  Lists can also be used to represent string data

    View Slide

  27.  
    #  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.  
    <>  #=>  "abc"  
    [?a,  ?b,  ?c]      #=>  'abc'  
    Strings

    View Slide

  28. #  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

    View Slide

  29. Modules
    •  Code organization is done via modules and
    functions
    defmodule  Ping  do  
       @moduledoc  """  
       Sample  module  
       """  
       
       #  Add  functions  here  
    end  
     

    View Slide

  30. 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  

    View Slide

  31. 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}  
     

    View Slide

  32. 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]  

    View Slide

  33. 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  

    View Slide

  34.  
     
    #  Implementation  of  reduce  
    def  reduce([],  value,  _)  do  
       value  
    end  
       
    def  reduce([head|tail],  value,  fun)  do  
       reduce(tail,  fun.(head,  value),  fun)  
    end  
    Recursion

    View Slide

  35. 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  

    View Slide

  36. 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  

    View Slide

  37. Demos

    View Slide

  38. 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)

    View Slide

  39. 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

    View Slide

  40. 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)

    View Slide

  41. 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)

    View Slide

  42. 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!

    View Slide

  43. Go Try Out Elixir
    •  Install Erlang
    •  Install Elixir
    •  Instructions for installation are at
    http://elixir-lang.org/getting_started/1.html

    View Slide

  44. Trevor Brown
    @Stratus3D
    github.com/Stratus3D
    stratus3d.com
    Code: 

    https://github.com/Stratus3D/elixir_erlang_for_rubyists
    Slides:
    https://speakerdeck.com/stratus3d

    View Slide