Erlang/OTP XX.12.2008 xmpp:astro@spaceboyz.net Geschichte Agner - - PowerPoint PPT Presentation

erlang otp
SMART_READER_LITE
LIVE PREVIEW

Erlang/OTP XX.12.2008 xmpp:astro@spaceboyz.net Geschichte Agner - - PowerPoint PPT Presentation

C3D2-Themenabend Erlang/OTP XX.12.2008 xmpp:astro@spaceboyz.net Geschichte Agner Krarup Erlang (1878 1929) Ericsson Language 1986, 1998 Konzept http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/ Hilfe


slide-1
SLIDE 1

C3D2-Themenabend

Erlang/OTP

XX.12.2008 xmpp:astro@spaceboyz.net

slide-2
SLIDE 2

Geschichte

Agner Krarup Erlang (1878 – 1929) Ericsson Language 1986, 1998

slide-3
SLIDE 3

Konzept

http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/

slide-4
SLIDE 4

Hilfe

$ erl -man erlang www.erlang.org www.trapexit.org

slide-5
SLIDE 5

Start

$ erl Erlang (BEAM) emulator version 5.6.4 [source] [async-threads:0] [kernel- poll:false] Eshell V5.6.4 (abort with ^G) 1>

slide-6
SLIDE 6

Start in emacs

M-x erlang-shell M-x erlang-mode C-c C-k

slide-7
SLIDE 7

Alles hat ein Ergebnis

Deja-vu

slide-8
SLIDE 8

Terme

foo. foo, bar. foo, bar, baz.

slide-9
SLIDE 9

Alternativen

foo; bar foo; bar; baz

slide-10
SLIDE 10

Variablen

beginnen mit Großbuchstaben, sind ungebunden oder gebunden

slide-11
SLIDE 11

Matching

1> T = 3. 3 2> T = 3. 3 3> T = 4. ** exception error: no match of right hand side value 4

slide-12
SLIDE 12

Ungenutzte Variablen

beginnen mit _ 1> _ = 23. 23 2> _ = 42. 42

slide-13
SLIDE 13

Module

  • module(worldctl).
slide-14
SLIDE 14

Funktionen

f() -> 23.

slide-15
SLIDE 15

Alternative Funktionen

f(foo) -> 23; f(bar) -> 42.

slide-16
SLIDE 16

Funktionen aufrufen

Im Modul: f() Aus anderem Modul: worldctl:f()

slide-17
SLIDE 17

Funktionen referenzieren

fun f/0 fun worldctl:f/2

slide-18
SLIDE 18

Keine Schleifen

recursion: see recursion

slide-19
SLIDE 19

Zählschleife

countdown(0) -> ok; countdown(N) -> countdown(N - 1).

slide-20
SLIDE 20

not tail-recursive

f() -> 1 + f().

slide-21
SLIDE 21

Anonyme Funktionen

fun() -> 23 end.

slide-22
SLIDE 22

Anonyme Funktionen mit Alternativen

fun(foo) -> 23; (bar) -> 42 end.

slide-23
SLIDE 23

Anonyme rekursive Funktionen?

slide-24
SLIDE 24

Y-Combinator

F = fun(F) -> F(F) end, F(F).

slide-25
SLIDE 25

case

case Term of Pattern1 -> Action1; Pattern2 -> Action2; Pattern3 when Guard3 -> Action3; Pattern4 when Guard4 -> Action4 end.

slide-26
SLIDE 26

if

if Guard1 -> Action1; Guard2 -> Action2; true -> DefaultAction end.

slide-27
SLIDE 27

Guards

... when V =/= 42 -> ... when V =/= 42, V =/= 23 -> ... when V =:= 42; V =:= 23 -> Nur BIFs!

slide-28
SLIDE 28

Built-in Functions (BIFs)

abs(Number) -> int() | float() apply(Fun, Args) -> term() | empty() apply(Module, Function, Args) -> term() | empty() ...

slide-29
SLIDE 29

Exceptions

2> catch 10 = 5 + 6. {'EXIT',{{badmatch,11}, [{erl_eval,expr,3}]}} catch ... -> Result | {'EXIT', {What, Where}}

slide-30
SLIDE 30

Exceptions generieren

1> catch erlang:error(foo). {'EXIT',{foo,[{erl_eval,do_apply,5}, {erl_eval,expr,5}, {shell,exprs,6}, {shell,eval_exprs,6}, {shell,eval_loop,3}]}} 2> catch exit(foo). {'EXIT',foo} 3> catch throw(foo). foo

slide-31
SLIDE 31

Datentypen

slide-32
SLIDE 32

Atome

foo, bar, baz, 'or anything with single quotes'.

slide-33
SLIDE 33

Nummern

Integers: 23, -42, 235. Floats: 3.141592653589793.

slide-34
SLIDE 34

Tupel

{foo, 23, 42}.

slide-35
SLIDE 35

Listen

[], [23, 42, 235], [23 | [42 | [235 | []]]].

slide-36
SLIDE 36

Key-Value Lists

1> process_info(self()). [{current_function,{erl_eval,do_apply,5}}, {initial_call,{erlang,apply,2}}, {status,running}, {message_queue_len,0}, {messages,[]}, {links,[<0.25.0>]}, {dictionary,[]}, {trap_exit,false}, {error_handler,error_handler}, {priority,normal}, {group_leader,<0.24.0>}, {total_heap_size,1974}, {heap_size,987}, {stack_size,24}, {reductions,1299}, {garbage_collection,[{fullsweep_after,65535},{minor_gcs,5}]}, {suspending,[]}]

slide-37
SLIDE 37

Strings

1> [$H, $e, $l, $l, $o, 32, 87, 111, 114, 108, 100]. "Hello World"

slide-38
SLIDE 38

lists:map/2

lists:map(fun(N) -> N * 2 end, Numbers).

slide-39
SLIDE 39

lists:filter/2

lists:filter(fun(N) -> N rem 2 == 0 end, Numbers).

slide-40
SLIDE 40

List Comprehensions (1)

[N * 2 || N <- Numbers, N rem 2 == 0].

slide-41
SLIDE 41

List Comprehensions (2)

[{N * 2, M} || N <- lists:seq(1,10), M <- lists:seq(1,10), M rem 2 == 0].

slide-42
SLIDE 42

lists:foldl/2

lists:foldl(fun(N, S) -> N + S end, 0, Numbers).

slide-43
SLIDE 43

References

1> make_ref(). #Ref<0.0.0.53>

slide-44
SLIDE 44

Weitere Datentypen

PIDs Nodes Ports

slide-45
SLIDE 45

Records

Strukturierte Tupel (vgl. struct in C)

slide-46
SLIDE 46

Record definieren

  • record(person, {name, age = 23}).
slide-47
SLIDE 47

Neuer Record

#person{} = {person, undefined, 23}, #person{name = "Hans"} = {person, "Hans", 23}, #person{name = "Frank", age = 42} = {person, "Frank", 42}.

slide-48
SLIDE 48

Auf Felder zugreifen

User#person.age, User#person.name.

slide-49
SLIDE 49

Pattern Matching mit Records

person_name(#person{name = Name}) -> Name; person_name(_) -> "Anonym".

slide-50
SLIDE 50

Records durch Kopie ändern

let_age(#person{age = Age} = P) -> P#person{age = Age + 1}.

slide-51
SLIDE 51

Binaries

read_header(<<HData:12/binary, RData/binary>>) -> <<ID:16/unsigned, QR:1, OpCode:4, AA:1, TC:1, RD:1, RA:1, Z:3, RCode:4, QDCount:16/unsigned, ANCount:16/unsigned, NSCount:16/unsigned, ARCount:16/unsigned>> = HData, {#dns_header{id=ID, qr=QR, opcode=OpCode, aa=AA, tc=TC, rd=RD, ra=RA, z=Z, rcode=RCode, qdcount=QDCount, ancount=ANCount, nscount=NSCount, arcount=ARCount}, RData}.

slide-52
SLIDE 52

Macros

  • define(FOO, 23).

?FOO.

slide-53
SLIDE 53

Macros & Parameter

  • define(SECOND(List), lists:nth(2, List)).

?SECOND([23, 42]).

slide-54
SLIDE 54

Konkurrente Programmierung

slide-55
SLIDE 55

Neuer Prozess

spawn(fun() -> ... end).

slide-56
SLIDE 56

Nachrichten senden

Pid ! Term.

slide-57
SLIDE 57

Nachrichten empfangen

receive Pattern1 -> Action1; Pattern2 when Guard2 -> Action2 end.

slide-58
SLIDE 58

Nachrichten empfangen mit Timeout

receive Pattern1 -> Action1; Pattern2 when Guard2 -> Action2 after Timeout -> TimeoutAction end.

slide-59
SLIDE 59

Linking

link(Pid), spawn_link(fun() -> ... end).

slide-60
SLIDE 60

trap_exit

process_flag(trap_exit, true), receive {'EXIT', From, Reason} -> ... end.

slide-61
SLIDE 61

Registering PIDs

register(queue, Pid), queue ! {enqueue, Item}.

slide-62
SLIDE 62

Sockets

slide-63
SLIDE 63

Active Sockets (1)

{active, false}; {active, once}; {active, true}.

slide-64
SLIDE 64

Active Sockets (2)

receive -> {tcp, Sock, Bin} -> Action1; {tcp_closed, Sock} -> Action2; {tcp_error, Sock, Reason} -> Action3 end.

slide-65
SLIDE 65

OTP

Open Telecom Platform — erweiterte Standardbibliothek

slide-66
SLIDE 66

gen_server

Was erwartet man von einem Server?

slide-67
SLIDE 67

Key-Value Storage Server (1)

  • module(kv).
  • export([loop/1]).

loop(KV) -> receive {From, get, Key} -> case lists:keysearch(Key, 1, KV) of {value, {Key, Value}} -> From ! {value, Value}; false -> From ! not_found end, NewKV = KV; {From, set, Key, Value} -> NewKV = [{Key, Value} | lists:keydelete(Key, 1, KV)], From ! set end, ?MODULE:loop(NewKV).

slide-68
SLIDE 68

Key-Value Storage Server (2)

  • export([start_link/0, get/2, set/3]).

start_link() -> spawn_link(fun() -> loop([]) end). get(Pid, Key) -> Pid ! {self(), get, Key}, receive {value, Value} -> Value; not_found -> exit(not_found) end. set(Pid, Key, Value) -> Pid ! {self(), set, Key, Value}, receive set -> ok end.

slide-69
SLIDE 69

gen_server API (1)

gen_server:start_link(Module, Args, Options)

  • > {ok, Pid} | ignore | {error, Error}

gen_server:start_link(ServerName, Module, Args, Options)

  • > {ok, Pid} | ignore | {error, Error}
slide-70
SLIDE 70

gen_server Callbacks (1)

init(Args)

  • > {ok, State}

terminate(Reason, State) code_change(OldVsn, State, Extra)

  • > {ok, NewState}
slide-71
SLIDE 71

gen_server Callbacks (2)

handle_call(Request, From, State)

  • > {reply, Reply, NewState}

| {noreply, NewState} | {stop, Reason, Reply, NewState} handle_cast(Request, State)

  • > {noreply, NewState}

| {stop, Reason, NewState} handle_info(Info, State)

  • > {noreply, NewState}

| {stop, Reason, NewState}

slide-72
SLIDE 72

gen_server API (2)

call(Name | Pid, Request)

  • > Reply

call(Name | Pid, Request, Timeout)

  • > Reply

cast(Name | Pid, Request)

slide-73
SLIDE 73

Mnesia

  • Relational
  • Transactional
  • In-Memory
  • Erlang-only
  • Distributed
slide-74
SLIDE 74

Mnesia: Creating a RAM- based table

  • record(person, {name, age}).

mnesia:create_table(person, [{attributes, record_info(fields, person)}]).

slide-75
SLIDE 75

Mnesia: Operations

read(Tab, Key)

  • > [Records]

write(Record) write(Tab, Record, LockKind) delete(Tab, Key, LockKind) delete_object(Record) delete_object(Tab, Record, LockKind)

slide-76
SLIDE 76

Mnesia: Transactions

mnesia:transaction(fun() -> ... end)

  • > {atomic, ResultOfFun}

| {aborted, Reason}

slide-77
SLIDE 77

Mnesia: Locking (1)

F = fun() -> Values = mnesia:read(table, Key), NewValues = waste_cpu(Values), [mnesia:write(Value) || Value <- NewValues] end, mnesia:transaction(F).

slide-78
SLIDE 78

Mnesia: Locking (2)

F = fun() -> mnesia:write_lock_table(table), Values = mnesia:read(table, Key), NewValues = waste_cpu(Values), [mnesia:write(Value) || Value <- NewValues] end, mnesia:transaction(F).

slide-79
SLIDE 79

Mnesia: Dirty Operations

dirty_read(Tab, Key) dirty_write(Record) dirty_delete(Tab, Key) dirty_delete_object(Record)

slide-80
SLIDE 80

Mnesia: Match Expressions (1)

mnesia:select(channel_user, [{#channel_user{client = Nick, channel = '$1'}, [], ['$1']}])

slide-81
SLIDE 81

Mnesia: Match Expressions (2)

mnesia:select(person, [{#person{age = '$1', _ = '_'}, [{orelse, {'<', '$1', 18}, {'>', '$1', 67}}], ['$_']}])