Modul (struktúra, szignatúra)

16.1. Kérdés.
Bizonyára sok emberrel megtörtént, hogy az otthon működő SML progija a beadáskor valamilyen inkompatíbilitási hibára hivatkozva le sem fordult.

16.1. Válasz.
Oktató: Inkompatíbilitásra akkor szokott panaszkodni az mosml, ha egy program egyes moduljait egy adott környezetben, más moduljait egy másik környezetben fordították le. Az adott esetben ez csak akkor lehetséges, ha (1) a forráskód (.sml) mellett a tárgykódot (.uo) is elküldte, és (2) a modul lefordítása a benti gépen valamilyen szintaktikai hiba miatt meghiúsult. Ilyenkor az otthon lefordított modult próbálja meg összeszerkeszteni az mosml a benti gépen előre lefordított modulokkal.

A kérdező folytatja: Nos: nekem sikerült újra működésre bírnom (a magyarázatát nem tudom, mázlimra egy régi működött, és a különbséget vizsgáltam meg). Írjátok be az első sorok közé: open TCikcakk.

Oktató: Igen, azt történt, amit leírtam: a Cikcakk modult nem tudta lefordítani. Amit csinált, az az egyik lehetséges megoldás. Megoldás az is, ha a TCikcakk modulban a

datatype dir = n | e | s | w | ne | nw | se | sw  
deklarációval létrehozott összes adatkonstruktorra, ahol csak használja őket, a teljes nevükkel hivatkozik, pl. TCikcakk.nw.

A kérdező folytatja: Betettem a Cikcakk modulba local ... in ... end ,,zárójelek'' közé, hogy szebb legyen. Otthon jó volt... Egy hasonló tartalmú, csak let-tel próbálkozó modulom fordítása meghiúsult... Ez van.

Oktató: A titok nyitja itt van! A modulok szintaxisárol nem nagyon beszéltünk az órákon, de aki megnézi a Moscow ML Language Overview Grammar for the Moscow ML module language c. fejezetét, láthatja, hogy a modulban csak deklarációk lehetnek, ezért csak local-deklaráció használható, let-kifejezés nem. A megoldás tehát egy ilyen szerkezet lehet:

structure x =
struct
  local
      open Math
  in
      val s = sin
  end
end

A kérdező folytatja: Ezt nem egészen értem, meg van tiltva az alábbi eset?
fun valami x =
      let
         open TCikcakk
      in
         x+2
      end
Elvileg az open csak val TCikcakk.nw típusú dolgokat tesz lehetővé, akkor ez miért baj? Másrészt otthon lefordult...

Oktató: Nem, ez nincs letiltva, hiszen itt egy függvény belsejében, egy lokális kifejezésben nyitja meg és használja a TCikcakk-ot. De ha a let-kifejezést egy struktúra (modul) törzsébe - a struct és az end közötti részbe - írja be, ahová csak deklarációkat lehet írni, akkor baj van, az hiba. Ugyanis bármilyen kifejezés, így bármilyen let-kifejezés is, csak egy deklaráció jobb oldalán használható.

Joggal kérezheti, hogy akkor az mosml értelmező miért hajlandó kiértékelni tetszőleges kifejezést, miért nem csak deklarációkat fogad el? Barátságos gesztusként, azért, hogy kényelmesebbé tegye az interaktív használatot! Ui. minden kifejezés elé odaképzeli a val it = deklarációkezdetet.

Ha tehát egy tetszőleges deklarációban, pl. egy local-deklarációban egy open-nel megnyit egy struktúrát (pl. a TCikcakk-ot), akkor az adott deklaráció érvényességi körében (scope) használhatja a megnyitott struktúrában deklarált nevek rövid változatát is (pl. az nw-t). Baj ebből csak akkor van, ha ugyanaz a név egynél több modulban van deklarálva, - azaz többszörösen van terhelve - és a rövid változatukat egyszerre szeretné használni. Ezt a láthatósági szabályok (visibility rules) nem engedik meg: egy később láthatóvá tett vagy deklarált név eltakarja a korábban láthatóvá tett vagy deklarált azonos alakú neveket.

16.2. Kérdés.
A házit fogadó gép melyik TCikcakk-ot használja? Mert nekem szuksegem van egy x irányra belső adminisztrációs felhasználásra, ezért bele kellett nyúlnom, hogy azt hozzárakjam.

16.2. Válasz.
Oktató: Finoman szólva nem javaslom, hogy módosítsa a TCikcakk modult! A specifikacio azért van, hogy betartsák. A teszteléskor csak a kiírásban megadott, ill. a keretprogrammal együtt letölthető specifikációt TCikcakk.sig, Cikcakk.sml) fogadja el a számítógép.

Képzelje el, mi lenne abból, ha ugyanezt akarná tenni egy igazán nagy rendszerben, ahol 13 másik programfejlesztő közösen dolgozik egy nagy projekten! Keressen más megoldást!

16.3. Kérdés.
Hogy lehet az sml-ben elérni azt, hogy a kimenet ilyesmi legyen: [[e,s,n,n,n]]? Talán rosszul adtam meg az irany típust? Ugyanis a kimenet egyelőre ilyen alakú: [[?e, ?s, ?n, ?n, ?n]].

16.3. Válasz.
Hallgató: Úgy, hogy nem a rövid n, e, w, s neveket használod, hanem a hosszú TSatrak.n, TSatrak.w stb. neveket. A kimenet ekkor ilyen lesz: [[TSatrak.n,TSatrak.w,...]], de ez nem baj, ez így jó.

A kérdező folytatja: Én TSatrak.n-et használok, de ettől függetlenül a fenti kérdőjeles megoldást kapom...

Oktató: Nézze meg az ,,egysátras'' mintamegoldást a <http://dp.iit.bme.hu/dp01s/egysator> címen a honlapon. Semmiféleképpen ne legyen az irany adattípus más struktúrában definiálva, mint a TSatrak.sml-ben.


Deklaratív programozás - FP-GYIK
2005. március 1.