From 54ba43b15f6875e1d65ebed772c5dd678bb4752c Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Tue, 10 May 2016 17:19:15 +0200 Subject: Initial commit --- .gitignore | 2 + Makefile | 27 +++++ erlang.mdwn | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ erlang.pdf | Bin 0 -> 157712 bytes l.erl | 104 ++++++++++++++++ 5 files changed, 525 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 erlang.mdwn create mode 100644 erlang.pdf create mode 100644 l.erl 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 Binary files /dev/null and b/erlang.pdf 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"). -- cgit v1.2.3