Erlang/OTP
for Rubyists
    Sean Cribbs
  KC.rb - July 2009
Ruby


Makes easy things trivial
  and hard things fun!
Erlang


 Makes easy things possible
and impossible things trivial!


     Orion Henry and Blake Mizerany
               (Heroku)
What is Erlang?

•Language, Runtime and Libraries (OTP)
•Developed and maintained by Ericsson
•Started mid 1980s, open-sourced 1998
Who uses it?
Who uses it?
Object-oriented
 Programming
object               object                   object
            object              object
                                                       object
 object                                    object
              object          object
object                                               object
         Object-oriented
  object  Programming                                object
  object                                    object
                     object       object
          object                                       object
                                           object
                        object
Object-oriented
 Programming
Concurrency-oriented
   Programming
process                  process
      process              process
                                                 process
process                                process
            process    process
                                            process
process                         process

   Concurrency-oriented
process
        Programming  process
  process                                 process
                             process
            process                           process
                      process
  process                              process
Concurrency-oriented
   Programming
Fault-tolerance
      IFF
 Concurrency
Error Handling

    Intra-process
    Inter-process
   Inter-machine
Sharing doesn’t scale
•Deadlocks
•Race Conditions
•Starvation
•Synchronization
•Data Locality
•Corruption
Message passing
 is the answer
Cool Features
•Concurrent
•Distributed
•Share-nothing
•Fault-tolerant
•Hot upgrades
•Highly available
Big Differences

•Functional - no objects
•Single assignment, few side-effects
•Initially challenging syntax
•Nothing like gems
Are you ready to be
UNCOMFORTABLY
  PARALLEL?
Spawn

Pid = spawn(
     fun()->
       io:format("Hello, Joe.")
     end).
Send Messages


  Pid ! {greet, “Joe”}.
Receive Messages
loop() ->
  receive
   {greet,S} ->
     io:format(“Hello, ~s”, [S]),
     loop();
   stop -> ok;
   _ -> loop()
  end.
Syntax Overview
Numbers

               1
             -1
           2501
            3.14
12345678987654321.987654321
Atoms

    foo
  type
  true
  false
 ‘EXIT’
Lists


        [1,2,3]
[“dog”, “cat”, “fish”]
   “hello, world”
Tuples
             {name, “Sean”}

{address, “8700 State Line Rd”, “Leawood”,
                   “KS”}

         {{line, 10},{column,30}}

          {{2009,7,14},{19,0,0}}
Binaries

           <<“chunk of bytes”>>

<<131,108,0,0,0,2,100,0,3,111,110,101,100
           ,0,3,116,119,111,
                  106>>
Some Weirdos

“abc” == [97,98,99]. % lists of bytes

true, false % atoms

$a == 97. % characters (ASCII)

P#person.name % compile-time struct
Assignment
Pattern Matching
Pattern Matching

         A = 5.

        B = 10.

    Group = “KC.rb”.
Pattern Matching

{Type, Value} = {username, “sean”}.

[{username, Value},
 {orders, Orders}] = [{username, “sean”},
              {orders, [1,2,3]}].
Single Assignment
    Really, this is just pattern matching.



A = 5.

A = A + 1. % error: badmatch (5 = 6)
Lists
functional programming’s old friend
List Operations

[First|Rest] = [1,2,3,4,5].

[H|T] = [1,2,3,4,5].

List1 ++ List2.
List Comprehensions
           Think select/filter + map.


A = [1,2,3,4,5].

[X * 2 || X <- A]. % [2,4,6,8,10]

[X || X <- A, X rem 2 == 0]. % [2,4]
Functions

even_or_odd(Num) ->
 if
   Num rem 2 == 0 ->
     even;
   true ->
     odd
 end.
Functions

even_or_odd(N) when N rem 2 == 0 ->
 even;

even_or_odd(N) ->
 odd.
Functions

even_or_odd(N) when is_number(N),
         N rem 2 == 0 ->
 even;

even_or_odd(N) when is_number(N) ->
 odd.
Anonymous Functions
           like lambda/proc, block


Double = fun(X) -> 2*X end.

Double(2). % 4

lists:map(Double, [1,2,3,4,5]).
  % [2,4,6,8,10]
No Loops!
 use recursion
A Little CS Theorem
   iterative === recursive
List “iteration”

print([]) ->
 ok;
print([H|T]) ->
 io:format(“~p”, [H]),
 print(T).
List “iteration”

print([]) ->
 ok;
print([H|T]) ->
 io:format(“~p”, [H]),
 print(T).
 print(T).
Normal Recursion
  loop()



           loop()



                    loop()



                             loop()
Tail Recursion
(aka tail-call optimization)




           loop()
Concurrent programs
can be complicated.
Behaviors
               “patterns”



•gen_server - client-server
•gen_fsm - state machine
•supervisor - fault-tolerance
How does it scale?

•Micro-benchmarks, arithmetic slow
•Best for network(ed) apps
•Campfire just as fast as C, ~ 2-4ms
•Near-linear speedup on multicores
•GC per-process, generational
Sean ! Questions.

Erlang/OTP for Rubyists