summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2016-05-10 17:19:15 +0200
committerGuido Günther <agx@sigxcpu.org>2016-05-10 17:19:15 +0200
commit54ba43b15f6875e1d65ebed772c5dd678bb4752c (patch)
tree3734e223934863eb9be63f8d549a10b292d450da
Initial commit
-rw-r--r--.gitignore2
-rw-r--r--Makefile27
-rw-r--r--erlang.mdwn392
-rw-r--r--erlang.pdfbin0 -> 157712 bytes
-rw-r--r--l.erl104
5 files changed, 525 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3594e15
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.beam
+*~
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..fb3ba84
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,27 @@
+SOURCE=erlang.mdwn
+PDF=$(SOURCE:mdwn=pdf)
+REVEALJS=$(SOURCE:mdwn=html)
+REVEALJS_VERSION=3.3.0
+
+IMAGES=$(wildcard *.png)
+ERL_FILES=$(wildcard *.erl)
+BEAM_FILES=$(ERL_FILES:erl=beam)
+
+all: ${REVEALJS} ${PDF} ${BEAM_FILES}
+
+${REVEALJS}: $(SOURCE) $(IMAGES) Makefile reveal.js
+ pandoc -V transition=fade -t revealjs -s ${SOURCE} -o ${REVEALJS}
+
+${PDF}: $(SOURCE) Makefile
+ pandoc -t beamer -s ${SOURCE} -o ${PDF}
+
+%.beam : %.erl
+ erlc $<
+
+reveal.js:
+ git submodule add https://github.com/hakimel/reveal.js.git $@
+ cd $@ && git checkout ${REVEALJS_VERSION}
+ git commit -m"Add reveal.js ${REVEALJS_VERSION}" reveal.js
+
+clean:
+ rm -f *.pdf *.html *.beam
diff --git a/erlang.mdwn b/erlang.mdwn
new file mode 100644
index 0000000..2915815
--- /dev/null
+++ b/erlang.mdwn
@@ -0,0 +1,392 @@
+---
+title: "Wissenswertes über Erlang"
+author: Guido Günther
+date: 2016-05-09
+---
+
+Who am I
+========
+
+* Free Software Hacker (Freelancing Software Developer)
+* Debian Developer since 2000
+* Contributed to libvirt-*, X11, Linux Kernel, GNOME, Calypso, …
+* FSFE Fellow and GNOME Foundation member
+* Rather new to Erlang
+
+Erl-what?
+=========
+
+* Developed at Ericsson in 1986
+* Open sourced 1998
+* Ericsson Language or Agner Krarup Erlang?
+* For telephone systems
+
+* Functional, concurrent programming language
+* Garbage collected runtime system
+* Erlang/OTP
+
+
+Erlang, Features
+================
+
+* Fault tolerant
+* Hot code replacements
+* Distributed
+* highly available - 12 years of uptime - nine 9s (30 ms / a)
+
+
+Projects
+========
+
+* ejabberd, Riak, CouchDB, RabbitMQ
+* WhatsApp, GitHub, Facebook, …
+
+
+You lack style - no, state!
+===========================
+
+---
+
+## Functional language ##
+
+f(x) = y
+
+---
+
+i = i + 3
+
+---
+
+~~i = i + 3~~
+
+---
+
+for (int i=0; i < 3; i++) do_something(i);
+
+---
+
+~~for (int i=0; i < 3; i++) do_something(i);~~
+
+---
+
+ 1> A=3.
+ 3
+ 2> A=4.
+ ** exception error: no match of right hand side value 4
+
+---
+
+## No means No ##
+
+* No imperative programming
+* No global variables and state
+* No pointers
+* No variable reassignments
+
+---
+
+* Yes, Higher Order Functions
+* Yes, Pattern Matching
+* Yes, Code Reloads
+* Yes, Lots of independent Processes
+
+---
+
+## Recursion to the Rescue ##
+
+ loop(X) -> loop(X, 0).
+
+ loop(X=0, Sum) -> Sum;
+ loop(X, Sum) -> loop(X-1, Sum+X).
+
+---
+
+## Recursion in Detail ##
+
+ loop(3) -> loop(3, 0)
+ loop(3,0) -> loop(3-1, 0+3)
+ loop(2,3) -> loop(2-1, 3+2)
+ loop(1,5) -> loop(1-1, 5+1)
+ loop(0,6) -> 6
+
+ 3 + 2 + 1 = 6
+
+---
+
+## Head to ~~Wall~~ Tail ##
+
+ A = [this, is, a, list].
+ [H|T] = A.
+
+---
+
+ rev(L) -> rev(L, []).
+
+ rev([], N) -> N;
+ rev([H|T], N) -> rev(T, [H] ++ N).
+
+---
+
+ rev([a,b,c,d]) -> rev([a,b,c,d], [])
+
+ rev([a|[b,c,d]], []) -> rev([b,c,d], [a] ++ [])
+
+ rev([b|[c,d]], [a]) -> rev([c,d], [b] ++ [a])
+
+ rev([c|[d]], [b,a]) -> rev([d], [c] ++ [b,a])
+
+ rev([d|[], [c,b,a]) -> rev([], [d] ++ [c,b,a])
+
+ rev([], [d,c,b,a]) -> [d,c,b,a]
+
+---
+
+## More pattern matching ##
+
+ A = {this, is, a, tuple}.
+ {_, _, _, B} = A.
+
+---
+
+ > B.
+ tuple
+ > _.
+ * 1: variable '_' is unbound
+
+---
+
+### Fun with Funs ##
+
+
+ F = fun (X) -> X*X end.
+ > F(3).
+ > F(ok).
+
+---
+
+ > F(3).
+ 9
+ > F(ok).
+ ** exception error: an error occurred when evaluating an arithmetic expression
+ in operator */2
+ called as ok * ok
+
+---
+
+## Success, Typing! ##
+
+Dialyzer
+
+ -spec foobar(atom()) -> [atom()].
+ foobar(App) -> …
+
+---
+
+Processes, which Processes
+==========================
+
+---
+
+## Spawning a process ##
+
+
+ F = fun(X) -> io:format("~p~n", [X]) end.
+ times(X, Args, C) -> ...
+
+ spawn(l, times, [F, "I'm a process", 3]).
+
+
+---
+
+
+ spawn(l, times, [F, "I'm a process", 3]),
+ spawn(l, times, [F, "I'm a process too", 3]).
+
+---
+
+
+## Concurrency for free! ##
+
+ "I'm a process"
+ "I'm a process too"
+ "I'm a process"
+ "I'm a process too"
+ <0.53.0>
+ "I'm a process"
+ "I'm a process too"
+
+
+---
+
+## Share(d) nothing ##
+
+
+ start_pong(Pid) -> …
+ pong(Pid) -> …
+
+ > P = l:start_pong(self()).
+ > P ! { ping, "foo" }.
+ > P ! giveup.
+
+
+---
+
+ > R = fun () -> receive M -> M end end.
+
+---
+
+ > R().
+ {pong,"hallo1"}
+ > R().
+ {pong,"hallo2"}
+
+---
+
+## Let it crash ##
+
+ 2> P ! {ping, 3}.
+ {ping,3}
+ 3>
+ =ERROR REPORT==== 8-May-2016::15:13:30 ===
+ Error in process <0.34.0> with exit value:
+ {badarg,[{io,format,[<0.25.0>,"pong: Received ping '~s'~n",[3]],[]},
+ {l,pong,1,[{file,"l.erl"},{line,57}]}]}
+
+---
+
+ 2> P ! whatever
+ Unknwown message asfasdf, giving up
+
+---
+
+## Linking processes ##
+
+ > process_flag(trap_exit, true).
+ > P = l:start_pong2(self()).
+ 3> P ! sadfsadf.
+ Unknwown message sadfsadf, giving upsadfsadf
+ 4> receive X -> X end.
+ {'EXIT',<0.35.0>,reason}
+
+---
+
+## Distributed nodes ##
+
+ $ erl -sname ping
+ $ erl -sname pong
+
+ register(spawn(...))
+
+---
+
+On pong
+
+ > P = l:start_pong3().
+
+On ping
+
+ > {pong, pong@bogon} ! {ping, "hello", self()}.
+ > {pong, pong@bogon} ! {ping, "hello", self()}.
+ > receive X -> X end.
+ {pong,"hello"}
+
+---
+
+ erlang:node().
+ erlang:nodes().
+
+---
+
+## Hot code replacements
+
+
+ version() -> …
+ c(l).
+
+---
+
+OTP
+===
+
+Open Telecommunication Platform
+
+---
+
+## Batteries inclued ##
+
+* EUnit
+* Mnesia
+* HTTP/SNMP/…
+* …
+
+---
+
+## Behaviours ##
+
+* gen_{server,fsm,event}
+* supervisor
+* application
+
+---
+
+Debugging
+=========
+
+---
+
+## Tracing Processes, Messges, … ##
+
+
+ erl -sname observer -hidden -run observer
+
+---
+
+## Tracing functions ##
+
+ dbg:start().
+ dbg:tracer().
+ % trace messages (m)
+ dbg:p(pong, m).
+
+---
+
+The greater Erlang Universe
+===========================
+
+* REST: [Webmachine](https://github.com/webmachine/webmachine)
+* JSON: [jiffy](https://github.com/davisp/jiffy)
+* YAML: [p1_yaml](https://github.com/processone/p1_yaml)
+* Build, run, test: [Rebar3](https://github.com/erlang/rebar3)
+* … your favorite erlang app goes here …
+
+---
+
+Extending Erlang
+================
+
+---
+
+## NIFs - Gesundheit! ##
+
+Native Implemented Functions
+
+---
+
+## C-Nodes
+
+See also
+========
+
+* [Elixir](http://elixir-lang.org/)
+* [LFE(Lisp flavored Erlang)](http://lfe.io/)
+* [Erlang on Xen](http://erlangonxen.org/)
+
+Further Reading
+===============
+
+* [Learn you some erlang](http://learnyousomeerlang.com/) - buy the book!
+* On Debian [/usr/share/doc/erlang-doc]()
+* Everywhere else: https://www.erlang.org/docs
+
+Questions?
+==========
diff --git a/erlang.pdf b/erlang.pdf
new file mode 100644
index 0000000..db181c4
--- /dev/null
+++ b/erlang.pdf
Binary files differ
diff --git a/l.erl b/l.erl
new file mode 100644
index 0000000..b33c650
--- /dev/null
+++ b/l.erl
@@ -0,0 +1,104 @@
+-module(l).
+-export([loop/1,
+ rev/1,
+ length/1,
+ times/3,
+ start_pong/1,
+ pong/1,
+ r/0,
+ start_pong2/1,
+ start_pong3/0,
+ pong/0,
+ version/0
+ ]).
+
+
+%%%%%%%%% Sum it up %%%%%%%%%%%%%%%%%%%
+
+
+loop(X) -> loop(X, 0).
+
+loop(_X=0, Sum) -> Sum;
+loop(X, Sum) -> loop(X-1, Sum+X).
+
+
+%%%%%%%%% Reverse a list %%%%%%%%%%%%%%
+
+
+rev(L) -> rev(L, []).
+
+rev([], N) -> N;
+rev([H|T], N) -> rev(T, [H] ++ N).
+
+
+%%%%%%%%%% Length of a list %%%%%%%%%%%
+
+
+length(L) -> length(L, 0).
+
+length([], N) -> N;
+length([_H|T], N) -> length(T, N+1).
+
+
+%%%%%%%%%% Run Fun X tmes %%%%%%%%%%%%
+
+times(_F, _Args, 0) -> ok;
+times(F, Args, X) ->
+ F(Args),
+ times(F, Args, X-1).
+
+
+%%%%%%%%%% Echo message sent %%%%%%%%%
+
+
+start_pong(Pid) ->
+ spawn(l, pong, [Pid]).
+
+pong(Pid) ->
+ receive
+ giveup ->
+ io:format("Pong finished~n", []);
+ {ping, Msg} ->
+ io:format("pong: Received ping '~s'~n", [Msg]),
+ Pid ! {pong, Msg},
+ pong(Pid);
+ Msg ->
+ io:format("Unknwown message ~p, giving up", [Msg]),
+ exit(reason)
+ end.
+
+r() ->
+ receive X -> X end.
+
+%%%%%%%%% Linked ping %%%%%%%%%%%%%%%
+
+start_pong2(Pid) ->
+ P = spawn(l, pong, [Pid]),
+ link(P),
+ P.
+
+%%%%%%%%% Distributed ping %%%%%%%%%%
+
+start_pong3() ->
+ P = spawn(l, pong, []),
+ register(pong, P),
+ P.
+
+pong() ->
+ receive
+ giveup ->
+ io:format("Pong finished~n", []);
+ {ping, Msg, Pid} ->
+ io:format("ping: Received ping '~s' from '~p~n", [Msg, Pid]),
+ Pid ! {pong, Msg},
+ pong();
+ Msg ->
+ io:format("Unknwown message ~p, giving up", [Msg]),
+ exit(reason)
+ end.
+
+
+%%%%%%%%% Code replacement %%%%%%%%%%%%%%%
+
+version() ->
+ io:format("This is version 1").