Fehlertolerante, nebenläufige Systeme auf der BEAM
Ausführen: Datei hallo.escript speichern und mit escript hallo.escript ausführen (Erlang/OTP von erlang.org; Projekte mit rebar3).
= ist ein Mustervergleich,, Funktionen mit .escript hallo.escript # Skript ausführen (wie in diesem Kurs)
erl # interaktive Shell: 1> io:format("Hallo~n").
erlc modul.erl # Modul übersetzen
erl -noshell -s modul start -s init stop
rebar3 new app meinapp # Projektgerüst
rebar3 shell # Shell mit geladenem Projekt; trennt, . beendet)when) fügen Bedingungen hinzu; case und if verzweigen== vergleicht Werte, =:= exaktfun name/arity verweist auf benannte Funktionen-export([main/1]).
fak(0) -> 1;
fak(N) when N > 0 -> N * fak(N - 1).
vorzeichen(N) when N > 0 -> positiv;
vorzeichen(N) when N < 0 -> negativ;
vorzeichen(0) -> null.
flaeche({kreis, R}) -> math:pi() * R * R;
flaeche({rechteck, B, H}) -> B * H;
flaeche({quadrat, S}) -> S * S.
begruesse(Name) -> begruesse(Name, "Hallo").
begruesse(Name, Gruss) -> Gruss ++ ", " ++ Name ++ "!".
main(_) ->
io:format("~p~n", [fak(10)]),
io:format("~p ~p ~p~n", [vorzeichen(5), vorzeichen(-2), vorzeichen(0)]),
io:format("~.2f ~p ~p~n", [flaeche({kreis, 1}), flaeche({rechteck, 3, 4}), flaeche({quadrat, 5})]),
io:format("~s~n", [begruesse("Mia")]),
io:format("~s~n", [begruesse("Tom", "Servus")]).lists-Modul mit map, filter, foldl, sort, seq, zip; hd/tl, ++, --[Ausdruck || Muster <- Liste, Bedingung]M#{k := v} (vorhandener Schlüssel) oder M#{k => v} (neu oder bestehend)main(_) ->
L = [5, 3, 9, 1, 7],
io:format("~p ~p ~p~n", [length(L), hd(L), tl(L)]),
io:format("~p~n", [[0 | L]]),
io:format("~p~n", [L ++ [8, 9]]),
io:format("~p~n", [lists:reverse(L)]),
io:format("~p~n", [lists:sort(L)]),
io:format("~p~n", [lists:sort(fun(A, B) -> A >= B end, L)]),
io:format("~p~n", [lists:map(fun(X) -> X * 2 end, L)]),
io:format("~p~n", [lists:filter(fun(X) -> X > 4 end, L)]),
io:format("~p~n", [lists:foldl(fun(X, Acc) -> X + Acc end, 0, L)]),
io:format("~p ~p~n", [lists:sum(L), lists:max(L)]),
io:format("~p~n", [lists:nth(2, L)]),
io:format("~p~n", [lists:member(9, L)]),
io:format("~p~n", [lists:seq(1, 5)]),
io:format("~p~n", [lists:split(2, L)]),
io:format("~p~n", [lists:sublist(L, 2, 3)]),
io:format("~p~n", [lists:zip([1, 2, 3], [a, b, c])]),
io:format("~p~n", [lists:flatten([1, [2, [3, 4]], 5])]),
io:format("~p~n", [lists:partition(fun(X) -> X rem 2 =:= 0 end, [1, 2, 3, 4, 5])]),
io:format("~p~n", [lists:any(fun(X) -> X > 8 end, L)]),
io:format("~p~n", [lists:all(fun(X) -> X > 0 end, L)]),
io:format("~p~n", [lists:duplicate(3, x)]),
io:format("~p~n", [lists:usort([3, 1, 2, 3, 1])]),
io:format("~p~n", [L -- [3, 9]]),
io:format("~p~n", [lists:keyfind(b, 1, [{a, 1}, {b, 2}])]),
io:format("~p~n", [lists:last(L)]).string bietet Funktionen<<...>>) und Bitsyntax parsen und bauen Protokolle bit-genau~ts gibt io:format Unicode aussumme([]) -> 0;
summe([K | R]) -> K + summe(R).
laenge(L) -> laenge(L, 0).
laenge([], N) -> N;
laenge([_ | R], N) -> laenge(R, N + 1).
mein_map(_, []) -> [];
mein_map(F, [K | R]) -> [F(K) | mein_map(F, R)].
fib(N) -> fib(N, 0, 1).
fib(0, A, _) -> A;
fib(N, A, B) -> fib(N - 1, B, A + B).
ggt(A, 0) -> A;
ggt(A, B) -> ggt(B, A rem B).
zaehle(0) -> fertig;
zaehle(N) -> zaehle(N - 1).
hanoi(0, _, _, _) -> [];
hanoi(N, Von, Nach, Hilf) ->
hanoi(N - 1, Von, Hilf, Nach) ++ [{N, Von, Nach}] ++ hanoi(N - 1, Hilf, Nach, Von).
main(_) ->
io:format("~p~n", [summe([1, 2, 3, 4])]),
io:format("~p~n", [laenge([a, b, c])]),
io:format("~p~n", [mein_map(fun(X) -> X + 1 end, [1, 2, 3])]),
io:format("~p~n", [fib(90)]),
io:format("~p~n", [ggt(48, 18)]),
io:format("~p~n", [zaehle(1000000)]),
io:format("~p~n", [hanoi(3, links, rechts, mitte)]).spawn startet Prozesse, ! sendet, receive empfängt (mit after als Timeout)spawn_link, spawn_monitor und trap_exit überwachen andere Prozesseregister/2 gibt Prozessen Namenecho() ->
receive
{From, Nachricht} ->
From ! {echo, Nachricht},
echo();
stop ->
ok
end.
main(_) ->
Pid = spawn(fun echo/0),
Pid ! {self(), hallo},
receive
{echo, Antwort} -> io:format("Antwort: ~p~n", [Antwort])
after 1000 -> io:format("Timeout~n")
end,
Pid ! {self(), welt},
receive
{echo, A2} -> io:format("Antwort: ~p~n", [A2])
end,
Pid ! stop,
timer:sleep(50),
io:format("lebt noch: ~p~n", [is_process_alive(Pid)]).gen_server kapselt Zustand mit init, handle_call und handle_castone_for_one, one_for_all, rest_for_one-behaviour(gen_server).
-export([main/1, init/1, handle_call/3, handle_cast/2]).
init(Start) -> {ok, Start}.
handle_call(stand, _Von, N) -> {reply, N, N};
handle_call({addiere, X}, _Von, N) -> {reply, N + X, N + X}.
handle_cast(zuruecksetzen, _N) -> {noreply, 0};
handle_cast({erhoehe, X}, N) -> {noreply, N + X}.
main(_) ->
{ok, Pid} = gen_server:start_link(?MODULE, 10, []),
io:format("~p~n", [gen_server:call(Pid, stand)]),
io:format("~p~n", [gen_server:call(Pid, {addiere, 5})]),
gen_server:cast(Pid, {erhoehe, 100}),
io:format("~p~n", [gen_server:call(Pid, stand)]),
gen_server:cast(Pid, zuruecksetzen),
io:format("~p~n", [gen_server:call(Pid, stand)]),
gen_server:stop(Pid).try ... catch Klasse:Grund ... after fängt error, throw und exit ab{ok, Wert} / {error, Grund} für erwartbare Fehlerets:new, insert, lookup, selectspawn und Nachrichtenteile(A, B) -> A / B.
main(_) ->
try teile(1, 0) of
Wert -> io:format("Wert ~p~n", [Wert])
catch
error:badarith -> io:format("durch null~n")
end,
try throw(mein_wurf)
catch throw:Was -> io:format("geworfen: ~p~n", [Was])
end,
try exit(beenden)
catch exit:Grund -> io:format("exit: ~p~n", [Grund])
end,
try error({eigener_fehler, 42})
catch error:{eigener_fehler, Code} -> io:format("Code ~p~n", [Code])
after io:format("after läuft immer~n")
end,
Ergebnis = (catch teile(4, 2)),
io:format("~p~n", [Ergebnis]),
try list_to_integer("abc")
catch error:badarg -> io:format("keine Zahl~n")
end,
try lists:nth(5, [1, 2])
catch error:function_clause -> io:format("zu kurz~n")
end.main(_) ->
io:format("~p~n", [erlang:system_info(otp_release) >= "20"]),
io:format("~p~n", [is_pid(self())]),
io:format("~p~n", [is_function(fun(X) -> X end)]),
io:format("~p~n", [erlang:abs(-7)]),
io:format("~p~n", [element(1, {a, b})]),
io:format("~p~n", [is_list("abc")]),
io:format("~p~n", [atom_to_list(hallo)]),
io:format("~p~n", [list_to_atom("welt")]),
io:format("~p~n", [length([])]),
io:format("~p~n", [min(3, 9)]),
io:format("~p~n", [rand:uniform(6) >= 1]),
io:format("~p~n", [is_binary(<<1>>)]),
io:format("~p~n", [erlang:process_info(self(), message_queue_len)]),
io:format("~p~n", [timer:tc(fun() -> ok end) =/= error]),
io:format("~p~n", [calendar:is_leap_year(2024)]),
io:format("~p~n", [calendar:day_of_the_week(2024, 3, 15)]),
io:format("~p~n", [filename:extension("a/b/c.txt")]),
io:format("~p~n", [filename:join(["a", "b", "c.txt"])]),
io:format("~p~n", [file:read_file("/nicht/da")]).