Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Programovací jazyk pro dnešní den: Erlang

Protože jsem se nedávno s kýmsi bavil o jazyku Erlang (v souvislosti s tím, že je v něm napsaný údajně nejvýkonnější existující webserver Yaws), pár dní jsem se tímto jazykem zabýval, protože jsem na to při „našem prvním setkání“ neměl příliš času.

Erlang původně vyvinula firma Ericsson pro ovládání telefonních ústředen, a to před více než 15 lety. Dnes je Erlang spravován open source komunitou a je pochopitelně k dispozici zdarma pro všechny myslitelné platformy. Pár základních informací je v tomto roztomilém starém videu, které upozorňuje na některé z hlavních přednosti Erlangu:

  • Erlang je od základu navržený tak, aby mohl být extrémně robustní a aby se části vaší aplikace mohly hroutit, updatovat a restartovat nezávisle na sobě, bez nutnosti zastavit celou aplikaci.
  • Erlang je od základu navržený tak, aby se v něm jednoduše komunikovalo mezi mnoha běžícími procesy.

Na oficiálních stránkách je k Erlangu podrobná dokumentace, kterou není problém přečíst a pochopit (samotné jádro jazyka je poměrně jednoduché, všechno ostatní je v knihovnách a ty jsou napsány převážně v Erlangu, takže je můžete studovat). Základní problém, bránící většímu rozšíření Erlangu, je ale podle mě v tom, že i když pochopíte syntaxi a princip jazyka, nepochopíte, k čemu vám to všechno může být dobré a bude vám to připadat jako šílenost.

K „bizarním“ vlastnostem tohoto funkcionálního jazyka patří například:

  • Pokud jednou přiřadíte proměnné nějakou hodnotu, už ji nemůžete změnit (vlastně to tedy není proměnná).
  • V Erlangu neexistují cykly nebo skoky, vše se dělá pomocí rekurze.
  • Erlang nezná hodnoty typu „string“. Můžete v programu napsat výraz „abcd“, ale je to přesně totéž, jako kdybyste napsali [97,98,99,100]. Je to prostě jen List složený z čísel. Ovšem ta čísla mohou být jakákoliv, tudíž můžete například bez problémů pracovat s Unicodem.
  • Hodně zábavy si užijete s „Pattern matching“ a operacemi s Listy (viz Caml, Haskell a spol.)

Na pointu těchto zdánlivě zvláštních pravidel přijdete až po nějaké době aktivního používání jazyka. Většina těchto omezení je totiž v jazyce proto, aby vás nutila programovat jistým způsobem, který je náročnější na přemýšlení, ale jehož výsledkem je přehlednější, robustnější a 5× až 10× kratší kód než ve většině ostatních jazyků!

Erlang je nejideálnější pro programování systémů pracujících v reálném čase, tady např. serverů nejrůznějšího druhu. U erlangových aplikací není výjimkou, že v nich běží současně stovky a tisíce procesů (což nejsou „procesy“ v klasickém smyslu toho slova, ale jednoduché erlangovské „miniprocesy“) a celá aplikace se vlastně skládá ze stovek a tisíců miniaturních serverů a klientů! Dovolte příklad:

Dejme tomu, že potřebujete mít nějakou globální datovou strukturu, ke které musí mít přístup různé rutiny vaší aplikace. V tradičnějších jazycích by se přístup k těmto datům řešil pomocí zámků, semaforů apod. V Erlangu je nejelegantnějším řešením vytvořit server, který se bude starat pouze o tuto strukturu (jiný proces se k ní nemůže nijak dostat) a jemuž budou ostatní části programu zasílat dotazy jako „Jaké telefonní číslo má Josef Novák?“, „Změn telefonní číslo Josefa Nováka na 609 696969“ nebo „Vymaž všechny Nováky“. Na rozdíl od ostatních jazyků tuto meziprocesovou komunikaci v Erlangu vytvoříte naprosto triviálně (systém se automaticky stará o buffering, timeouty a podobné věci) a dokonce není nejmenším problémem, aby různé procesy běžely na různých fyzických počítačích (na principu jejich programování se tím nic nemění)!

Erlang má vlastní interaktivní shell, který pro nováčka vypadá dost strašidelně, ale jeho síla je v tom, že si ho snadno přizpůsobíte a vytvoříte si vlastní vývojové prostředí. Já jsem si například během prvního dne experimentování napsal vlastního démona, který při mém programování sleduje erlangovské zdrojáky v daném adresáři, automaticky pozná pokud se některý z nich změní a v takovém případě daný modul odstraní z běžícího systému, nahradí nově zkompilovanou verzí (pokud v ní nejsou chyby) a restartuje moji aplikaci (aniž bych musel opouštět textový editor, ve kterém pracuji). To vše je naprogramováno v pár řádcích a vůbec to nepůsobí dojmem nějaké „prasárny“ (jak by to působilo v jiných jazycích, které podobné věci také umí).

Pokud vás tenhle krátký úvod zaujal, v Erlangu je napsán například Jabber server eJabberd a 3D modelovací program Wings3D, přičemž zdrojový kód obou je překvapivě krátký a přehledný a v obou případech ho můžete volně studovat, protože jde o open source aplikace.

Tommy
Tommy (neregistrovaný)
27. 9. 2006 20:16 Nový

Zkoušel jsem volat na to číslo 609 696969 ale žádnej Novák tam

celé vlákno

Zkoušel jsem volat na to číslo 609 696969 ale žádnej Novák tam není!

smrduty oposum
smrduty oposum (neregistrovaný)
27. 9. 2006 20:31 Nový

Tommy

celé vlákno

Tommy: Ja jsem totiz predtim poslal serveru pozadavek na vymaz a tak ustredna uz cislo na novaka nezna :)

so
so (neregistrovaný)
27. 9. 2006 20:50 Nový

Zdroják na ten loader / unloader by náhodou nebyl?

celé vlákno

Zdroják na ten loader / unloader by náhodou nebyl? Rád bych do něj nahlédnul.

Jinak, co se týče těch vlastností Erlangu, pravděpodobně je spíše ocení někdo, kdo má alespoň základní znalosti nějakého funkcionálního jazyka. Předpokládám, že většina vysokoškolsky vzdělaných lidí v oboru IT zná aspoň trochu Lisp, když už nic. Takže bych to neviděl tak beznadějně. ;-)

František Fuka
František Fuka (neregistrovaný)
27. 9. 2006 21:18 Nový

<pre>-module(starter )

celé vlákno

[3]:<pre>-module(starter).
-export([stop/0, start/0, restart/0, bootup/1]).

%% called after recompilation
restart() -> test:run().

stop() ->
case is_pid(whereis(star­ter)) of
true ->
starter ! stop,
stopped;
_Else ->
already_stopped
end.

start() ->
case stop() of
stopped -> io:format("Starter stopped.~n");
already_stopped -> true
end,
io:format("Starting starter~n"),
Pid = spawn_link(?MODULE, bootup,["."]),
register(starter, Pid).

bootup(Dir) ->
put(dir, Dir),
put(delay, 2000),
put(modifs, none),
loop().

loop() ->
receive
stop ->
exit(normal);
recompiled ->
?MODULE:restart()
after get(delay) ->
% io:format("watching dir ~p...~n",[get(di­r)]),
Files = filelib:wildcar­d("*.erl",get(dir)),
Modifs = lists:map(fun(File) -> {File, filelib:last_mo­dified(File)} end,Files),
% io:format("---~p~n",[Modifs]),
case put(modifs, Modifs) == Modifs of
true -> true;
false -> recompile(Files)
end
end,
loop().

recompile(Files) ->
Recompile = fun(File) ->
Result = compile:file(File),
% Result = code:load(File),
io:format("Com­piled: ~p~n",[Result]),
case Result of
{ok, Module} when Module /= starter -> code:purge(Module), code:delete(Mo­dule);
_ -> ok
end
end,
lists:foreach(Re­compile, Files),
io:format("---Recompiled~n"),
starter ! recompiled.</pre>

František Fuka
František Fuka (neregistrovaný)
27. 9. 2006 21:18 Nový

(aha, tak s indentaci to bohuzel nepujde)

celé vlákno

(aha, tak s indentaci to bohuzel nepujde)

so
so (neregistrovaný)
27. 9. 2006 21:28 Nový

Díky

celé vlákno

Díky. I v případě, že má náhodou Erlang taky sémanticky odsazování, je ten zdroják pro studium užitečný. emerge erlang už doběhl, takže bych to mohl vyzkoušet. :-)

so
so (neregistrovaný)
27. 9. 2006 21:29 Nový

Uf: sémanticky významné odsazování (ala Python &co)

celé vlákno

Uf: sémanticky významné odsazování (ala Python &co)

M jako Molitan
M jako Molitan (neregistrovaný)
27. 9. 2006 22:13 Nový

"zobrazit zdroj" v prohlizeci to

celé vlákno

[5] "zobrazit zdroj" v prohlizeci to jisti

so
so (neregistrovaný)
27. 9. 2006 22:31 Nový

Dobrý tip

celé vlákno

Dobrý tip, díky

gd
gd (neregistrovaný)
27. 9. 2006 23:02 Nový

Tak na všech IT univerzitách se dnes tuším učí nějaký zástupce jayka

celé vlákno

Tak na všech IT univerzitách se dnes tuším učí nějaký zástupce jayka funkcionálního programování, např. huskel

frettie
frettie (neregistrovaný)
28. 9. 2006 8:45 Nový

jo haskell se na MUNI FI uci, ale opravdu je to haskell, ne huskel :))

celé vlákno

jo haskell se na MUNI FI uci, ale opravdu je to haskell, ne huskel :))

jinak, funkcionalni programovanni jde zaplat panbuh mimo mne :)

Dr.Sid
Dr.Sid (neregistrovaný)
28. 9. 2006 10:07 Nový

Vsude se to uci

celé vlákno

Vsude se to uci .. a stejne to nikdo nepouziva.

so
so (neregistrovaný)
28. 9. 2006 10:23 Nový

Neřekl bych, že nikdo

celé vlákno

Neřekl bych, že nikdo. Např. Linspire používá nějakou dobu Haskell jako hlavní vývojový prostředek pro svoje nástroje, některé prvky funkcionálního programování jsou často používané např. programátory Pythonu. Docela dost lidí používá MLDonkey napsaný v OCAML. No a samotný Erlang se samozřejmě používá taky. ;-)

zoul
zoul (neregistrovaný)
28. 9. 2006 11:04 Nový

12> Přinejmenším se člověk naučí myslet jinak než procedurálně

celé vlákno

12> Přinejmenším se člověk naučí myslet jinak než procedurálně. Mám jeden semestr funkcionálního programování za sebou a i když se jen těžko objektivně posuzuje, jestli mi ty znalosti vysloveně pomáhají v praxi, řekl bych že jo. Člověk se naučí běžně zacházet s rekurzí a některé funkcionální konstrukce se dají použít v Perlu, Pythonu, JavaScriptu nebo XSL.

Adam
Adam (neregistrovaný)
28. 9. 2006 11:07 Nový

No

celé vlákno

No ... tyhle funkcionalni jazyky jsou sice pekny na hrani, ale pro realny pouziti (mozna s vyjimkou nejakejch specialnich vypoctu) jsou podle me naprosto k nicemu.
Vytvoreny kod v podstate neni mozne udrzovat a silne pochybuju, ze by se v nem vyznal nekdo jiny nez autor.
Ano, vysledny kod je sice kratsi, ale kdo se ma vyznat v konstrukcich typu : podle vysledku rek. volani zavolej jeste jednou sama sebe s parametrem jako vysledkem jeste jednoho rek. volani. (nekecam, opravdu jsem to v jednom programu potreboval). ... predstavte si potom jak, kdyz mate kod, prijit na to, co to dela ...
(znam jenom Hasskell, mozna Erlang bude pouzitelnejsi)

NecoOTomVim
NecoOTomVim (neregistrovaný)
28. 9. 2006 11:16 Nový

Ehm, pokud jsou funkcionalni jazyky tak "nepochopitelne"

celé vlákno

Ehm, pokud jsou funkcionalni jazyky tak "nepochopitelne" a "neuzitecne", tak proc je microsoft ochotne vykrada do sveho ce sharp? (a nerekne tvurcum puvodnim napadu ani diky)
Anonymni funkce a closures, automaticka inference (odvozeni) typu, to bude v dalsi verzi microsoftiho jazyka. Java chysta neco podobneho.
Samozrejme tomu bude Microsoft rikat nejakou svoji prihlouplou manazerskou hantyrkou a za dva roky to bude umet kazdy "Visual" vidlak a propagandisti z Microsoftu o tom budou extaticky vykrikovat na svych blozich coze prevratneho zase vymysleli.
Chytri programatori jako je Frantisek a ja ovsem tohle zname a pouzivame uz dnes.
Mimochodem, cely humbuk kolem webovych sluzeb a posilani zprav ("enterprise", XML, blablabla) je vlastne opakovanym vynalezanim Erlangu - paralelni zpracovani s komunikaci pomoci zprav.

Jirka
Jirka (neregistrovaný)
28. 9. 2006 11:25 Nový

Idealni programovaci jazyk pro

celé vlákno

Idealni programovaci jazyk pro BeOS.

pkm
pkm (neregistrovaný)
28. 9. 2006 16:25 Nový

Pokud vím, tak BeOS je plně poplatný době svého vzniku - je v C++

celé vlákno

Pokud vím, tak BeOS je plně poplatný době svého vzniku - je v C++.

Funkcionální programování mě zajímá, pač to používají chytří lidi a jsou produktivní. Osobně s tím mám problém - "impedance mismatch" je killer.

Jakub Dusek
Jakub Dusek (neregistrovaný)
28. 9. 2006 19:35 Nový

NecoOTomVim

celé vlákno

NecoOTomVim: Ale spis min nez vic :) Podobny problem se resi uz dlouho, existuje x ruznych objektovych reseni, ale az XML webove sluzby odbourali zbytecne technologicke naroky na strane integrovanych systemu / procesu. Muzu nejak jednoduse zavolat proces Erlangu z libovolne jine platformy, kdyz jsou XML webove sluzby jen opakovanim jeho funkcnosti? Pokud ano, dalo by se uvazovat o tom ze XML webove sluzby by mohli byt nahrazeny Erlangem, jinak je to jen jedno z milionu kvalitnich sudlitek pro homogenni prostredi, pro heterogenni prostredi jsou tu vyborne XML webove sluzby.

Taky nemam rad buzzwords, ale je potreba rozlisovat kdy se za nimi skryva skutecne uzitecna technologie...

BTW, to ze nekdo vykrada funkcnosti z funkcionalniho jazyka do objektoveho jazyka o kvalite toho funkcionalniho jako celku nerika vubec nic :) Cimz samozrejme netvrdim ze kvalitni neni.

NecoOTomVim
NecoOTomVim (neregistrovaný)
28. 9. 2006 23:39 Nový

Dobre, dve malo zname pravdy:

celé vlákno

[19]
Dobre, dve malo zname pravdy:
XML je zvast a XML webove sluzby jeste vetsi. Naucte se Lisp a pi-calculus a Erlang, pochopite principy a to je dulezitejsi nez reklamni blaboleni dobre placenych konzultantu a jine pakaze.


> Ad "nekdo vykrada funkcnosti z funkcionalniho jazyka do objektoveho jazyka o kvalite toho funkcionalniho jako celku nerika vubec nic :)"
Ale rika. Obtizne problemy (jako je garbage collection, napojeni na imperativni prostredi atd.) vyresi nektery akademik ve funkcionalnim jazyku a kvalitne to popise ve sve prednasce, dobre placeny zvanil od javy nebo od microsoftu si to poslechne a pak udela to same pod jinym nazvem.
Je to smutne, ale je to tak.

Jakub Dusek
Jakub Dusek (neregistrovaný)
29. 9. 2006 8:17 Nový

Pletete hrusky s jablkama :) Znovu a pomaleji

celé vlákno

[20] Pletete hrusky s jablkama :) Znovu a pomaleji: jak mi pomuze Lisp a pi-calculus a Erlang vyresit integracni problemy ktere resi XML webove sluzby? Zatim mam dojem ze o XML webovych sluzbych vite jen prave to co placaji marketingovy manazeri. Tentokrat prosim konkretni odpoved, ne nadavani na uspesnejsi konzultanty :)

Michal Kára
Michal Kára (neregistrovaný)
29. 9. 2006 8:45 Nový

Pokud vim, na posilani zprav byl zalozeny uz SmallTalk

celé vlákno

Pokud vim, na posilani zprav byl zalozeny uz SmallTalk, coz je (pokud se nemylim) rok 1975.

Jinak v programovani nebyva problemem ani tak pocet radku, ale zejmena udrzovatelnost. A tady musim souhlasit s [15], ze to neni silna stranka funkcionalnich jazyku. To, ze se eventuelne nejake konstrukce prenasi do imperativnich jazyku neznamena, ze jsou lepsi (protoze resit co je "lepsi" je vpodstate nesmysl), ale ze se mohou obcas hodit.

NecoOTomVim
NecoOTomVim (neregistrovaný)
29. 9. 2006 18:59 Nový

Vy zase pletete dohromady principy a jejich konkretni implementaci

celé vlákno

[21] Vy zase pletete dohromady principy a jejich konkretni implementaci.
Jeste jednou a poomalu.
Pi-calculus a Erlang vas nauci premyslet o paralelnich procesech ktere komunikuji pomoci zprav, a tyto znalosti pak muzete v omezene mire pouzit ve svete webovych sluzeb (bohuzel neni nic lepsiho).

Jakub Dusek
Jakub Dusek (neregistrovaný)
29. 9. 2006 21:52 Nový

Na tom se shodneme :)

celé vlákno

[23] Na tom se shodneme :) Na zacatku diskuse byly WS humbuk a zvast a ted uz neni nic lepsiho, takze jsem s vyvojem diskuse spokojen :)

NecoOTomVim
NecoOTomVim (neregistrovaný)
29. 9. 2006 22:46 Nový

Vite co

celé vlákno

Vite co, nacpete si do zadni brany spicate zavorky a vykriknete pri tom "aaach integraaaace eeenterprise".

NecoOTomVim
NecoOTomVim (neregistrovaný)
29. 9. 2006 22:49 Nový

Webove sluzby resi jen tu nejjednodussi cast celeho problemu

celé vlákno

Webove sluzby resi jen tu nejjednodussi cast celeho problemu - format prenosu dat.
To ze s paralelnim programovanim jsou spojene mnohe dalsi (a tezsi) problemy ovsem xml salati ani netusi, mozna tak za pet let s velkou slavou prijdou na to co vi erlang uz ted.

zoul
zoul (neregistrovaný)
30. 9. 2006 13:03 Nový

Tak dóst, tohle nikam nevede

celé vlákno

Tak dóst, tohle nikam nevede. Webové služby možná řeší jen vzájemnou komunikaci, ale to kvůli tomu, že nic jiného řešit nechtěly. XML je praktická věc, stačí se rozhlédnout kolem. To, že nějaké technologie nabízely funkce podobné XML už dřív, na užitečnosti a úspěchu XML vůbec nic nemění. Proč by XML saláti měli vědět něco o paralelním programování nevím… Každá technologie má své výhody a nevýhody, a ne vždycky vyhraje ta „technicky nejlepší“. Nebylo by dobré se s tím smířit?

Jakub Dusek
Jakub Dusek (neregistrovaný)
1. 10. 2006 22:14 Nový

[25, 26] Preju Vam

celé vlákno

[25, 26] Preju Vam, aby se Vam v nejblizsi dobe podarilo ziskat trochu nadhledu z vyssi perspektivy, bez toho takhle dalekosahle soudy o technologiich, ktere vyvolaly tuhle debatu opravdu delat nejdou. Kazdopadne tahle diskuse pro me po "argumentu" [25] ztratila jakykoliv smysl a dal ji nebudu marnit cas :)

quo
quo (neregistrovaný)
2. 10. 2006 8:24 Nový

Po [25] jsem si opet uvedomil syrovou skutecnost

celé vlákno

Po [25] jsem si opet uvedomil syrovou skutecnost, ze jsme na blogu (ehm) zakladatele kompostu. Jen tak dal. Az na dren.

NecoOToVim
NecoOToVim (neregistrovaný)
2. 10. 2006 8:26 Nový

Jaja, pro oravdu se clovek

celé vlákno

Jaja, pro oravdu se clovek zlobi.

Pichi
Pichi (neregistrovaný)
2. 7. 2007 21:05 Nový

Sice po asi roce, ale přece

celé vlákno

Sice po asi roce, ale přece. Tak nevím jestli mám FF tykat, ale asi jo. Ten loader je hezkej. Jen taková drobnost, když si přečteš Making Reliable Systems with Presence of Software Errors od Joe Armstronga a kriticky se podíváš na ten svůj výtvor tak je to pěkné až na jednu věc. Bez put a get by to bylo hezčí :-) Jde čistě jen o to, že to není úplně čisté. Krom toho na přepnutí na nový kód není potřeba ten starý purgovat, stačí když se zavolá plně kvalifikovaná funkce a už to běží na novém kódu. Tedy překompiluješ a můžeš na to zapomenout, dřív nebo později všechny běžící procesy migrtují na nový kód.

-module(starter).
-export([stop/0, start/0, restart/0, bootup/1]).
%% called after recompilation

restart() -> test:run().
stop() ->
case is_pid(whereis(star­ter)) of
true ->
starter ! stop,
stopped;

_Else ->
already_stopped
end.
start() ->
case stop() of
stopped -> io:format("Starter stopped.~n");

already_stopped -> true
end,
io:format("Starting starter~n"),
Pid = spawn_link(?MODULE, bootup,["."]),
register(starter, Pid).

bootup(Dir) ->
loop(Dir, 2000, none).
loop(Dir, Delay, Modifs) ->
receive

stop ->
exit(normal);
recompiled ->
?MODULE:restart()
after Delay ->
% io:format("watching dir ~p...~n",[Dir]),

Files = filelib:wildcar­d("*.erl",Dir),
NewModifs = lists:map(fun(File) -> {File, filelib:last_mo­dified(File)} end,Files),
% io:format("---~p~n",[Modifs]),
case NewModifs == Modifs of
true -> true;

false -> recompile(Files)
end
end,
loop(Dir, Delay, NewModifs).
recompile(Files) ->
Recompile = fun(File) ->

Result = compile:file(File),
% Result = code:load(File),
io:format("Com­piled: ~p~n",[Result]),
case Result of
{ok, Module} when Module /= starter -> code:purge(Module), code:delete(Mo­dule);
_ -> ok

end
end,
lists:foreach(Re­compile, Files),
io:format("---Recompiled~n"),
starter ! recompiled.

Pichi
Pichi (neregistrovaný)
2. 7. 2007 22:01 Nový

Tak odladěno a vyzkoušeno

celé vlákno

Tak odladěno a vyzkoušeno. Zajímavé, že mě nenapadlo si takovou věcičku taky udělat. Jen tak pro ty rozumbrady aka Dusek. Jen si zkuste napast něco co si skompiluje novou verzi sebe sama a bez přerušení činnosti pokračuje s novou verzí kódu. V erlangu brnkačka viz následující kód.

Pročištěná verze:

-module(starter).
-export([stop/0, start/0, loop/1]).
-define(dir, ".").
-define(timeout, 2000).
%% called after recompilation

stop() ->
case is_pid(whereis(star­ter)) of
true ->
starter ! stop,
stopped;
_Else ->
already_stopped
end.

start() ->
case stop() of
stopped -> io:format("Starter stopped.~n");
already_stopped -> true
end,
io:format("Starting starter~n"),
Pid = spawn_link(?MODULE, loop,[{?dir, ?timeout, none}]),
register(starter, Pid).

loop({Dir, Delay, Modifs}=S) ->
receive
stop ->
ok;
_ -> loop(S)
after Delay ->
% io:format("watching dir ~p...~n",[Dir]),
Files = filelib:wildcar­d("*.erl",Dir),
NewModifs = lists:map(fun(File) -> {File, filelib:last_mo­dified(File)} end,Files),
% io:format("---~p~n",[Modifs]),
case NewModifs == Modifs of
true -> loop(S);
false -> recompile(Files),
?MODULE:loop({Dir, Delay, NewModifs})
end
end.

recompile(Files) ->
Recompile = fun(File) ->
Result = compile:file(File),
io:format("Com­piled: ~p~n",[Result]),
case Result of
{ok, Module} -> code:purge(Module),
code:delete(Mo­dule),
code:load_file(Mo­dule);
_ -> ok
end
end,
lists:foreach(Re­compile, Files),
io:format("---Recompiled~n").

Zasílat nově přidané příspěvky e-mailem