A Modula3 programozási nyelv

Bevezetés

Bevezetés

A nyelv történetéről

A Modula-3 fejlesztése 1986-ban kezdődött. Távoli ősét, a Modula nyelvet Niklaus Wirth fejlesztette ki a Pascal tapasztalatait felhasználva. Ezt a nyelvet később a Digital Equipment Corporation vette gondozásba, és létrehozta a Modula-2 és Modula-2+ nyelveket. A Modula-3 a DEC és az Olivetti közös projektje volt. Olyan nyelv létrehozása volt a cél, mely hű marad a Modula-2 és a Modula-2+ szelleméhez, és egyszerű, biztonságos és kipróbált tulajdonságokkal tud többet. A nyelv támogatja interfészek, objektumok, generic-ek kezelését, folyamatok vezérlését, kivételkezelést és altípus relációt is. Automatikus szemétgyűjtéssel rendelkezik és képes az ún. unsafe (nem biztonságos) műveletek megkülönböztetésére. A Modula-2 néhány problematikus jellemzőjét eltávolították, mint pl. a variáns rekordot. A Modula-3 lényegesen egyszerűbb, mint néhány hasonló erejű programozási nyelv.

Pár általános megjegyzés

A Modula-3 a Pascal nyelvcsaládhoz tartozik, de vannak olyan vonásai is, amik inkább a C/C++ programozóknak lesz ismerős.

Case sensitive
Minden foglalt szót és kulcsszót nagybetűvel kell írni. Az azonosítókra pedig mindig olyan írásmóddal kell hivatkoznunk, ahogy definiáltuk őket. Például Main és main két különböző azonosító.

Egyetlen főmodul
Minden Modula-3 programnak egy és csak egy főmodulja van (main module). Kisebb programokban ez az egyetlen modul.

Megjegyzések
A megjegyzések a szokott "(* megjegyzés *)" formátumúak, és több sort is átölelhetnek.

BEGIN/END a blokkosítás
A kód blokkjai BEGIN és END közé záródnak. Egy fontos megjegyzés az is, hogy a procedure-t lezáró END-et követnie kell az eljárás nevének.

Pontosvesszővel elválasztott utasítások
Az utasításokat pontosvesszővel kell elválasztani.

A nyelv áttekintése

Modulok, interfészek

A Modula-2 egyik legsikeresebb jellemzője a modulok közötti interfészek explicit leírásának biztosítása. Az interfészek és modulok leírását gyakorlatilag egy az egyben örökölte a Modula-3 is.

A modulok a Modula-3 alapvető építőkövei. A modulok deklarációk nevesített gyűjteményei, beleértve a konstans-, típus-, változó-, és alprogram deklarációkat. Egy modul a saját deklarációit elérhetővé teheti más modulok - a kliensei - számára. Ezt a kívülről látható részt írják le az interfészek, amelyek mellett a moduloknak van rejtett implementációs része is.

Egy modul importálja azokat az interfészeket amelyeket felhasznál, és exportálja azokat, melyeket megvalósít. Az interfészek használatával biztonságosan tudjuk moduljainkat külön fordítani. Nem kell félni attól, hogy valamely hivatkozásunk érvénytelenné válik egy már lefordított modulban. Egy-egy modul kifelé csak az interfésze(i)n keresztül látszik, amely lehetőséget nyújt arra, hogy programunkat átlássuk anélkül, hogy a részleteket ismernénk. Ez a karbantartást, és a betanulást egyszerűsíti le nagy mértékben.

A főprogramnak (modulnak) exportálnia kell a Main interfészt. Egy implementációs részhez több interfész is tartozhat.

Objektum-elvű jellemzők

Az objektumokkal, mint nyelvi elemekkel, a 60-as évek közepén először a Simula nyelvben találkozhatunk. A Modula-3 objektumelvű jellemzői nagymértékben hasonlítanak a Simula hasonló jellemzőihez:

Az objektum típusok kombinálása a Modula-2 átlátszatlan típusaival egy merőben áj lehetőséget adnak a kezünkbe: a részlegesen átlátszatlan típus fogalmát. A részlegesen átlátszatlan típusban némely mező, illetve metódus látható kívülről, mások nem.

Generic

A generic modul igazából egy váz, melyet konkrét interfészekkel paraméterezve egy konkrét modult, illetve interfészt kaphatunk. Annak érdekében, hogy a nyelv egyszerűsége ne csorbuljon, a generic a Modula-3-ban csak modul szinten jelenik meg mint nyelvi elem. Nincs tehát generic típus, vagy eljárás. A generic paramétere is csak teljes interfész lehet. Természetesen ez valójában nem jelent megszorítást, hiszen szabadon írhatunk csak egy típust, vagy eljárást tartalmazó modult is, bár ez természetesen némi plusz munkával járhat. Cserébe viszont átláthatóbb struktúrájú kódot kapunk. Ugyancsak az egyszerűségre való törekvésnek köszönhető, hogy a genericekkel kapcsolatban nincs külön típusellenőrzés. Az implementációkra van bízva, hogy a generic példányosításánál típusellenőrzést végezzenek a paraméterekre vonatkozóan.

Párhuzamos folyamatok

A Modula-2-ben a párhuzamosság biztosítása gyakorlatilag kimerült a korutinok támogatásával. Ennél a nyelv fejlesztői komolyabb támogatást akartak, így került a Modula-2+ nyelv párhuzamos eszköztára - mely a Mesa nyelv eszköztárára épül, némi egyszerűsítésekkel - különösebb változtatás nélkül a Modula-3 nyelvbe. Ez az eszköztár Hoare féle monitorokra épül.

Biztonság

Egy nyelvi jellemző nem biztonságos (unsafe) , ha annak nem megfelelő használata a futtató környezet nem megfelelő működéséhez vezethet, amikor is a program további futása nem a nyelv szemantikájának megfelelően folytatódik. Egy egyszerű példa erre, ha tömböt másolunk az indexhatárok ellenőrzése nélkül. Ennek ellentéte a biztonságos kód/jellemző, mely nem okoz ilyen galibákat, bárhogy is használjuk (természetesen a nyelv adta kereteken belül). Kívánatosnak látszik, hogy el tudjuk különíteni a programunk biztonságos és nem biztonságos szeleteit. Erre a Modula-3 nyelvi szinten ad lehetőséget. A nyelvben található néhány "unsafe" művelet. Ezeket csak olyan modulokban használhatunk, melyeket "unsafe"-nek jelölünk. Egy modul, ha "unsafe" modult használ, szintén "unsafe"-nek kell lennie. A fordító ezután minden olyan modulban, mely biztonságos (azaz nem "unsafe") megakadályoz minden olyan szituációt, mely a futtatókörnyezet összeomlásához vezethetne. "Unsafe" modulokban ez a programozóra van bízva.

Szemétgyűjtés

Tipikus programozói hiba egy adatstruktúra felszabadítása ágy, hogy még van rá élő hivatkozás. Ekkor, ha el szeretnénk érni ezután a meglévő hivatkozáson keresztül az adatokat, futásidejű hibát kapunk (jó esetben), vagy akár az egész futtatórendszer is összeomolhat. Ugyanilyen probléma, ha nem szabadítjuk fel azokat a tárterületeket, amelyekre nincs több hivatkozás. Ezt memóriafolyásnak (memory leaking) nevezzük. Ekkor a programunk által foglalt memória folyamatosan nő, míg végül az összes rendelkezésre álló memóriát elfogyasztva erőforrás hiányában abortál. összevetve az előző fejezetben elmondottakkal, láthatjuk, hogy egy memóriaterület explicit felszabadítása tipikus "unsafe" művelet. Ennek elkerülésére vezették be a Modula-3-ban az őrzött (traced) referenciákat. Az ezek által fogalt memóriaterületet nem lehet explicit módon felszabadítani. Ehelyett a futtatókörnyezet ágynevezett szemétgyűjtő algoritmussal szabadítja fel automatikusan a már nem használt memóriaterületeket. Ezzel párhuzamosan lehetőség van őrizetlen (untraced) referenciák használatára is, melyeket a programozó szabadon kezelhet, a hozzájuk tartozó memóriaterületet explicit felszabadíthatja. Természetesen ennek használatára csak "unsafe" modulokban kerülhet sor.

Kivételkezelés

A Modula-3 kivételkezelése követi a más nyelvekben megszokott szabályokat. A kivételek bárhol kiválthatók a programban, és a hívási láncban felfelé terjedve elkaphatók, illetve, ha nincs megfelelő kivételkezelő, akkor a futtatókörnyezetnek átadódva a program megállását okozzák.

Típusok

A Modula-3 nyelv erősen típusos, mint az Algol családjába tartozó nyelvek általában. Az erős típusosság felvet néhány problémát, melyeket a különböző nyelveken más és más módon oldottak meg. Például:

A Modula-3-ban a típusrendszert megpróbálták annyira egységesíteni, amennyire csak lehet. Néhány alapszabály, melyet követtek: Ezenkívül fontos megjegyezni, hogy a Modula-3-ban (ellentétben például a Modula-2-vel) strukturális típusekvivalenciát alkalmaznak.

Egyszerűség

A Modula-3 nyelv tervezésekor az egyik elsődleges szempont volt, hogy annyira egyszerű legyen a nyelv, amennyire csak a kifejezőerő és az átláthatóság csökkentése nélkül ez lehetséges. Ezért tudatosan arra törekedtek, hogy csak a legfontosabb, leghasználhatóbb jellemzők maradjanak a nyelvben, és minden más, amely különösebb fájdalom nélkül megoldható más, egyszerűbb, átláthatóbb eszközökkel is, elvetésre ítéltetett. A fő szempontok a következők voltak:

A fenti jellemzők önmagukban nem hordoznak nagy újdonságot, hiszen szinte kivétel nélkül más nyelvekből lettek átvéve. De így összességükben és rendszerükben egy hatékony és egyszerűségéhez mérten kivételesen "erős" nyelvet adnak.