Elixir: The Power of Erlang for Rubyists

9fa60df551b9e4282c0519bf173c2e04?s=47 Trevor Brown
September 01, 2014

Elixir: The Power of Erlang for Rubyists

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

9fa60df551b9e4282c0519bf173c2e04?s=128

Trevor Brown

September 01, 2014
Tweet

Transcript

  1. Elixir: The Power of Erlang for Rubyists Trevor Brown

  2. Trevor Brown Sarasota, Fl Ruby, JavaScript, Erlang, and Elixir Erlang

    developer at Voalte
  3. What is Erlang?

  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
  5. Processes and the Erlang VM

  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
  7. Erlang VM CPU   CPU   CPU   CPU  

    Thread   Thread   Thread   Thread   Virtual  Machine  Process   Process   Process   Process   Process   Process   Process  
  8. Processes <0.81.0>

  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
  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
  11. Processes are Actors •  Implements the actor model •  Processes

    encapsulate state •  Elixir’s processes are more object-oriented than objects in object-oriented languages
  12. Processes Processes communicate via message passing <0.44.0>   <0.83.0>  

    <0.74.0>   <0.76.0>  
  13. What is Elixir?

  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
  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
  16. What Elixir is Not

  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
  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
  19. Elixir Basics

  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  
  21. Binaries and Numbers #  Binaries   <<97,98,99>>      

    #  Integers   12       #  Floats   23.5  
  22. Tuples •  Ordered collection of elements with a fixed size.

    •  Often used in pattern matching
  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
  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.
  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
  26. String(ish) Types •  No true string type •  Elixir represents

    strings as binaries underneath •  Lists can also be used to represent string data
  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.   <<?a,  ?b,  ?c>>  #=>  "abc"   [?a,  ?b,  ?c]      #=>  'abc'   Strings
  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
  29. Modules •  Code organization is done via modules and functions

    defmodule  Ping  do      @moduledoc  """      Sample  module      """          #  Add  functions  here   end    
  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  
  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}    
  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]  
  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  
  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
  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  
  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  
  37. Demos

  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)
  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
  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)
  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)
  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!
  43. Go Try Out Elixir •  Install Erlang •  Install Elixir

    •  Instructions for installation are at http://elixir-lang.org/getting_started/1.html
  44. Trevor Brown @Stratus3D github.com/Stratus3D stratus3d.com Code: 
 https://github.com/Stratus3D/elixir_erlang_for_rubyists Slides: https://speakerdeck.com/stratus3d