Erlang Introduction
Upcoming SlideShare
Loading in...5
×
 

Erlang Introduction

on

  • 1,263 views

 

Statistics

Views

Total Views
1,263
Views on SlideShare
1,263
Embed Views
0

Actions

Likes
0
Downloads
6
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Erlang Introduction Erlang Introduction Presentation Transcript

  • Erlang Introduction Serhiy Oplakanets, Lviv 2012Friday, February 10, 12
  • Classification • high-level • general-purpose • garbage-collected • dynamically typed • functional • concurrentFriday, February 10, 12
  • $ erl Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:4:4] [rq: 4] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.5 (abort with ^G) 1>Friday, February 10, 12
  • SyntaxFriday, February 10, 12
  • Data TypesFriday, February 10, 12
  • 1> 2 + 2. 4 2> 3 * 5. 15 3> 7 / 6. 1.1666666666666667Friday, February 10, 12
  • 1> []. [] 2> [1, 2, 3]. [1,2,3] 3> [101,104,63]. "eh?"Friday, February 10, 12
  • 1> "a string". "a string" 2> [97,32,115,116,114,105,110,103]. "a string"Friday, February 10, 12
  • 1> $H. 72 2> $e. 101 3> $l. 108 4> $o. 111 5> [$H, $e, $l, $l, $o]. "Hello"Friday, February 10, 12
  • 1> true. true 2> false. false 3> true == false. false 4> false == false. true 5> true /= false. trueFriday, February 10, 12
  • 1> atom. atom 2> anotherAtom. anotherAtom 3> One more atom?. One more atom?Friday, February 10, 12
  • 4> is_atom(One more atom?). trueFriday, February 10, 12
  • 1> is_atom(true). true 2> is_atom(false). trueFriday, February 10, 12
  • 1> {1,2,3}. {1,2,3} 2> {16, "hello"}. {16,"hello"} 3> {3.14, "Pi", {"foo", bar}}. {3.14,"Pi",{"foo",bar}}Friday, February 10, 12
  • Invariable VariablesFriday, February 10, 12
  • 1> Variable = "value". "value" 2> AnotherVariable = 128. 128Friday, February 10, 12
  • 1> R = 5, Pi = 3.14. 3.14 2> Pi. 3.14 3> Pi * R * R. 78.5Friday, February 10, 12
  • 1> X = 1. 1 3> X = 2. ** exception error: no match of right hand side value 2 4> X = 1. 1 ?!?!Friday, February 10, 12
  • Pattern MatchingFriday, February 10, 12
  • 1> X = 1, Y = 1. 1 2> X = Y. ???Friday, February 10, 12
  • 1> UnboundVariable. * 1: variable UnboundVariable is unboundFriday, February 10, 12
  • 1> X = 1. 1 2> X. 1 3> Y. * 1: variable Y is unbound 4> Y = 2. 2 5> Y. 2Friday, February 10, 12
  • 1> User = {"John", "Doe", 35}. ... 2> {Name, Surname, Age} = User. ... 3> Name. "John" 4> Age. 35Friday, February 10, 12
  • 1> User = {"John", "Doe", 35}. ... 2> {Name, Surname} = User. ** exception error: no match of right hand side value {"John","Doe",35}Friday, February 10, 12
  • 2> User = {"John", "Doe", 35}. ... 3> {Name, "Doe", 35} = User. ... 4> Name. "John"Friday, February 10, 12
  • 1> User = {"John", "Doe", 35}. ... 2> {Name, _, Age} = User. ... 3> Age. 35 4> Name. "John"Friday, February 10, 12
  • 1> _ = 1. 1 2> _. * 1: variable _ is unbound 5> _ = 3. 3Friday, February 10, 12
  • 1> [Head | Tail] = [1,2,3]. [1,2,3] 2> Head. 1 3> Tail. [2,3]Friday, February 10, 12
  • 1> [1 | [2 | [3]]]. [1,2,3]Friday, February 10, 12
  • Modules and FunctionsFriday, February 10, 12
  • -module(test). -export([main/0]). main() -> "Hello".Friday, February 10, 12
  • 1> test:main(). "Hello"Friday, February 10, 12
  • -module(test). -export([factorial/1]). factorial(0) -> 1; factorial(N) -> N * factorial(N - 1).Friday, February 10, 12
  • $ erlc test.erl $ erl ... 1> test:factorial(3). 6 2> test:factorial(5). 120Friday, February 10, 12
  • -module(logger). -export([log/1, log/2]). log(Msg) -> {"info", Msg}. log(Level, Msg) -> {Level, Msg}. --------------------8<-------------------- 1> logger:log("Some info message."). {"info","Some info message."} 2> logger:log("error", "Kernel panic!"). {"error","Kernel panic!"}Friday, February 10, 12
  • log(Msg) -> log("info", Msg). log(Level, Msg) -> {Level, Msg}.Friday, February 10, 12
  • Function GuardsFriday, February 10, 12
  • -module(test). -export([fib/1]). fib(0) -> 0; fib(1) -> 1; fib(N) when N > 0 -> fib(N-1) + fib(N-2).Friday, February 10, 12
  • test:fib(0). 0 3> test:fib(1). 1 5> test:fib(8). 21 6> test:fib(-23). ** exception error: no function clause matching test:fib(-23)Friday, February 10, 12
  • % Refactored factorial function: factorial(0) -> 1; factorial(N) when is_integer(N) and (N > 0) -> N * factorial(N - 1); factorial(_) -> {error, "Invalid argument"}.Friday, February 10, 12
  • 7> factorial:factorial(3). 6 8> factorial:factorial(0). 1 9> factorial:factorial(-1). {error,"Invalid argument"} 10> factorial:factorial("a"). {error,"Invalid argument"}Friday, February 10, 12
  • Concurrency • any function can become a process • process is a function executing in parallel • process shares nothing with other processesFriday, February 10, 12
  • Processes/Actors • processes are extremely lightweight and fast • ~15 seconds to spawn 100k processes on my machine (MacBook Pro 8.1, OSX)Friday, February 10, 12
  • spawn(Module, Function, Arguments) -> PidFriday, February 10, 12
  • Any function can become a processFriday, February 10, 12
  • 8> io:format("Hello~n"). Hello ... 2> spawn(io, format, ["Hello~n"]). Hello ...Friday, February 10, 12
  • -module(actor). -export([loop/0]). loop() -> receive die -> io:format("Exiting~n") end.Friday, February 10, 12
  • 2> Pid = spawn(actor, loop, []). <0.40.0> 3> is_process_alive(Pid). true 4> Pid ! die. Exiting die 5> is_process_alive(Pid). falseFriday, February 10, 12
  • loop() -> receive die -> io:format("Exiting~n"); Msg -> io:format("Got: ~p~n", [Msg]) end.Friday, February 10, 12
  • 2> Pid = spawn(actor, loop, []). ... 3> is_process_alive(Pid). true 4> Pid ! "Hello". Got: "Hello" ... 5> is_process_alive(Pid). falseFriday, February 10, 12
  • loop() -> receive die -> io:format("Exiting~n"); Msg -> io:format("Got: ~p~n", [Msg]), loop() end.Friday, February 10, 12
  • 2> Pid = spawn(actor, loop, []). ... 3> Pid ! "Hello". Got: "Hello" 4> is_process_alive(Pid). true 5> Pid ! "Hello again!". Got: "Hello again!" 6> is_process_alive(Pid). true 7> Pid ! die. Exiting 8> is_process_alive(Pid). falseFriday, February 10, 12
  • Processes are executed in parallel and share no dataFriday, February 10, 12
  • -module(counter). -export([loop/1]). loop(N) -> receive increment -> loop(N + 1); decrement -> loop(N - 1); print -> io:format("Current counter value: ~w~n", [N]), loop(N) end.Friday, February 10, 12
  • 2> Counter = spawn(counter, loop, [0]). ... 3> Counter ! increment. ... 4> Counter ! increment. ... 5> Counter ! print. Current counter value: 2 ... 6> Counter ! decrement. ... 7> Counter ! print. Current counter value: 1Friday, February 10, 12
  • 2> C1 = spawn(counter, loop, [0]). <0.40.0> 3> C2 = spawn(counter, loop, [10]). <0.42.0> 4> C1 ! increment, C1 ! increment, C1 ! print. Current counter value: 2 5> C2 ! decrement, C2 ! print. Current counter value: 9Friday, February 10, 12
  • Distributed ErlangFriday, February 10, 12
  • spawn(Node, Module, Function, Args) -> PidFriday, February 10, 12
  • 1> spawn(DistributedNode, test, factorial, [10]).Friday, February 10, 12
  • s erl -sname slave -setcookie 123!@#qwe ... (slave@Serhiys-MacBook-Pro)1> node(). slave@Serhiys-MacBook-ProFriday, February 10, 12
  • $ erl -sname master -setcookie 123!@#qwe ... (master@Serhiys-MacBook-Pro)1> net_adm:ping(slave@Serhiys-MacBook-Pro). pong (master@Serhiys-MacBook-Pro)3>spawn(slave@Serhiys- MacBook-Pro, factorial, factorial, [100]). 933262154439441526816992388562667004907159682643816 214685929638952175999932299156089414639761565182862 536979208272237582511852109168640000000000000000000 00000 <6619.52.0>Friday, February 10, 12
  • Fault ToleranceFriday, February 10, 12
  • -module(actor). -export([loop/0]). loop() -> receive N -> S = math:sqrt(N), io:format("sqrt(~p) = ~p~n", [N,S]), loop() end.Friday, February 10, 12
  • 2> Pid = spawn(actor, loop, []). ... 3> Pid ! 4. sqrt(4) = 2.0 ... 5> Pid ! "a". =ERROR REPORT==== 24-Jan-2012::14:06:02 === Error in process <0.40.0> ... 6> is_process_alive(Pid). falseFriday, February 10, 12
  • Supervisors • supervisors monitor processes and take actions on exit signals • process linking does the trickFriday, February 10, 12
  • start() -> spawn(actor, restarter, []). restarter() -> process_flag(trap_exit, true), Pid = spawn_link(actor, loop, []), register(myActor, Pid), receive {EXIT, _Pid, _Reason} -> io:format("Process crashed. Restarting~n"), restarter() end.Friday, February 10, 12
  • 2> actor:start(). 3> myActor ! 4. sqrt(4) = 2.0 4> myActor ! "foo". Process crashed. Restarting =ERROR REPORT==== Error in process <0.41.0> ... 5> is_process_alive(whereis(myActor)). true 6> myActor ! 9. sqrt(9) = 3.0Friday, February 10, 12
  • Other great features • Hot code loading • OTP Framework •Friday, February 10, 12
  • Simplicity • You just learned • ~70% of Erlang syntax • most major abstractions: modules, functions and processes • most of the core data typesFriday, February 10, 12
  • Complexity • Erlang/OTP is a complex framework • Learning it takes time and practiceFriday, February 10, 12
  • Bad Stuff • syntax • Strings • code organization • libraries • underestimated complexity of OTP and concurrent applications generally • your colleagues will not understand you :)Friday, February 10, 12
  • Practical Application • Notable uses: • Facebook (Chat) • CouchDB • RabbitMQ • Membase • RiakFriday, February 10, 12
  • How to learn Erlang?Friday, February 10, 12
  • http://learnyousomeerlang.com/Friday, February 10, 12
  • Erlang getting started guide: http://www.erlang.org/doc/getting_started/intro.htmlFriday, February 10, 12
  • Programming Erlang: Software for a Concurrent World http://pragprog.com/book/jaerlang/programming-erlangFriday, February 10, 12
  • $ erlFriday, February 10, 12
  • [$Q, $u, $e, $s, $t, $i, $o, $n, $s, $?].Friday, February 10, 12
  • Thank youFriday, February 10, 12