Az ERLANG programozási nyelv

Alprogramok, modulok

Terminológia

Vizsgáljuk a következő modult:

-module(list2). %1 -export([flat_length/1]) %2 flat_length(List) -> flat_length(List, 0). %3 flat_length([H|T], N) when list(H) -> flat_length(H, flat_length(T,N)); %4 flat_length([H|T], N) -> flat_length(T, N + 1); %5 flat_length([], N) -> N. %6

A kommenteket a % karakter előzi meg.

Az 1. sor a moduldeklaráció. Az 1. és 2. sorok elején levő ‘-’ jel az attribútum prefix. (module(lists2) példa attribútumra)

A 2. sor alapján a flat_length/1 függvény a modul export részébe tartozik, a modulon kívülről is elérhető.

A 3. sor a flat_length egyattribútumú függvény definícióját tartalmazza. Ez a függvény egyetlen klózból áll. A flat_length(List) a klóz feje, a ‘->’ jelet követő rész pedig a klóz törzse.

A 4.-6. sorokban a flat_length/2 függvény definíciója található. Ez a függvény három klózból áll, ezek pontosvesszővel vannak elválasztva, az utolsó klózt pedig pont zárja le.

A 4. sorban a when kulcsszó és a ‘->’ jel között egy őrfeltételt találunk. A függvény törzse akkor értékelődik ki, ha a fej illeszkedik a hívás módjához és az őrfeltétel teljesül.

A flat_length/2 első klóza őrfeltételes klóz, a többi őrfeltételmentes klóz.

A flat_length/2 lokális függvény, azaz nem hívható a modulon kívülről. (ui. a flat_length/2 nem szerepel a modul export részében)

A C-s és Pascalos gyakorlattal ellentétben az ERLANG-ban lehetőség van azonos nevű, ám eltérő argumentumszámú függvények definiálására.

Klózok

A függvény klózokból épül fel. Ezek pontosvesszővel vannak elválasztva. Minden klóz fejből, opcionális őrfeltételből és törzsből áll.

A klóz feje a függvény nevéből áll, melyet a függvény argumentumai követnek, vesszővel elválasztva. Minden argumentum egy érvényes minta. Ha függvényhívás történik, a végrehajtandó törzs szekvenciális kereséssel kerül kiválasztásra, az első sikeresen illeszkedő klózfejhez tartozó törzs hajtódik végre.

Az őrfeltétel egy feltétel, melynek a klóz kiválasztása előtt teljesülnie kell.

Egy őrfeltétel lehet egy egyszerű ellenőrzés vagy ellenőrzések vesszővel elválaszott sorozata. Egy egyszerű ellenőrzés lehet aritmetikai összehasonlítás, term összehasonlítás vagy egy előredefiniált rendszer tesztfüggvény hívása. Az őrfeltételeket tekinthetjük a mintaillesztés egyfajta kiterjesztésének is. Felhasználó által definiált függvények nem szerepelhetnek őrfeltételekben.

Egy őrfeltétel kiértékelésekor az összes benne szereplő ellenőrzés kiértékelődik, nem definiált sorrendben. Ha az őrfeltétel igaz, a klóz törzse végrehajtódik. Ellenkező esetben a következő klóz kerül sorra.

Példa:

factorial(N) when N==0 -> 1; factorial(N) when N > 0 -> N * factorial(N-1).

A klóztörzs egy vagy több kifejezés szekvenciájából áll, melyek vesszővel vannak elválasztva. A kifejezések szekvenciálisan értékelődnek ki. A szekvencia értéke az utolsó kifejezés értéke lesz.

Például:

factorial(N) when N > 0 -> N1 = N - 1, F1 = factorial(N1), N*F1.

Modulrendszer

Az ERLANG modulrendszere lehetővé teszi, hogy a programot kisebb egységekre, modulokra osszuk. Minden modulnak saját névtere van, vagyis szabadon használhatunk egyazon függvénynevet több modulban is.

Egy függvény akkor látható más modulokból is, ha szerepel a tartalmazó modul export deklarációs részében.

Példa:

-module(lists). -export([reverse/1]). reverse(L) -> reverse(L, []). reverse([H|T], L) -> reverse(T, [H|L]); reverse([], L) -> L.

A program a reverse/1 egyargumentumú és reverse/2 kétargumentumú függvényeket definiálja A reverse/1 hívható a modulon kívülről is. A reverse/2 csak a modulon belül látható. A reverse/1 és reverse/2 függvények teljesen függetlenek egymástól, az ERLANG tehát különbséget tesz azonos nevű, de eltérő argumentumszámú függvények között. Tehát egy függvényt csak neve és argumentumszáma határoz meg.

Modulok közti hívások

Két mód van adott modulból egy más modulban definiált függvény hívására.

-module(sort1). -export([reverse_sort/1, sort/1]). reverse_sort(L) -> list1:reverse(sort(L)). sort(L) -> lists:sort(L).

A reverse/1 függvény hívása lists1:reverse(L) módon a teljesen minősített függvényhívás. Ezzel szemben használható a közvetett minősítésű függvényhívás is:

-module(sort2). -import(lists1, [reverse/1]). -export([reverse_sort/1, sort/1]). reverse_sort(L) -> reverse(sort(L)). sort(L) -> lists:sort(L).

Esetenként a két hívás együttes alkalmazására van szükség. Ha például több különböző modul exportál ugyanolyan nevű függvényt, mindenképpen teljesen minősített függvényhívásra van szükség.