Eiffel-ohjelmointikieli HtmlSaku #21, 12.4.1997
Mikko Koivunalho, mikkoi@utu.fi


E iffel on nuori ohjelmointikieli. Sen ensimmäinen malli julkistettiin vuonna 1985. 12 vuotta ei ole pitkä ikä, varsinkaan kun ottaa huomioon, että kieli on tullut laajemmin tunnetuksi vasta parina viime vuotena. Niinpä Eiffelillä onkin ollut hyvää aikaa puhdistautua alkuvaiheen virheistä ja suunnitteluvioista. Kuitenkin sen määrittelyä on muutettu merkittävästi vain kerran, 1991, ja nykyinen Eiffel-malli, Eiffel 3, on sittemmin pysynyt muuttamattomana.

Eiffel-standardi on pysynyt samanlaisena, koska Eiffelin kehitys on pääosin yksissä käsissä: Bertrand Meyerin ja ISE:n (Interactive Software Engineering), ja kielen standardina pidetään Meyerin kirjaa "Eiffel, The Language". Nimensä Eiffel on saanut ranskalaiselta insinööriltä Alexander Gustave Eiffeliltä [efe'l] (1832-1923). Kielen suunnittelussa Meyer on seurannut Eiffelin omaa ideologiaa, jonka mukaan rakenteiden itsensä (pääosin rautaa, esim. Eiffelin torni) tulee olla kaunista katseltavaa symmetrisyydessään, yksinkertaisuudessaan ja täsmällisyydessään.

Eiffel on uusi kieli, jonka suunnittelussa on tieten tahtoen hylätty suuri joukko vanhemmissa kielissä käytettäviä ohjelmointimetodeja ja otettu käyttöön uusia. Paitsi että se on täysiverinen oliosuuntautunut kieli, se on myös pikkutarkka ja perinteisiin kieliin nähden syntaksiltaan yksinkertainen sekä ohjelmoijalta runsasta etukäteissuunnittelua vaativa.

Eiffelin filosofiaa ymmärtääkseen on tarkasteltava perinteisiä kieliä ja niiden ongelmia. Jo kauan ennen Eiffeliä ohjelmoinnin metodologian tutkijat esittivät, että mm. GOTO-komento ei missään nimessä kuulu asialliseen ohjelmointiin, koska se sallii ohjelman suoritusjärjestyksen täydellisen rikkomisen. Tämä ja vastaavanlaiset piirteet, mm. funktion tai ohjelman keskeytys ennen loppua, on täysin poistettu Eiffelistä.

Edelleen Eiffelin syntaksia on radikaalisti yksinkertaistettu laittamalla siihen vain kolme suorituksenohjauslauseketta: yksi ehtolauseke, yksi toistolauseke ja yksi valintalauseke (moniehto-, C:ssä switch). Perinteisissä kielissähän näitä on monissa ollut kasapäin, esim. C-kielen while-, do-while- ja for-silmukat. Miksi laittaa monenlaisia toistolausekkeita sotkemaan ohjelmakoodia, kun kerran yksi riittää kaikkiin tarpeisiin hiukan sovittamalla?

Eiffel on myös voimakkaasti tyypitetty kieli. Tavanomaisten vanhoista kielistä tuttujen tyyppien kuten REAL, INTEGER ja BOOLEAN lisäksi siihen on "sisäänrakennettu" muita tyyppejä, jotka useimmista kielistä puuttuvat kokonaan tai ne on toteutettu kielen itsensä ulkopuolella, esim. vektori, lineaarinen lista, pino ja jono.

Oliokieli

E dellä kirjoitin "sisäänrakennettu" lainausmerkeissä. Ilmaisu sallittakoon minulle, vaikka nyt selitänkin, miksi näin ei oikeastaan voi olla: Eiffel on puhdas oliokieli, joten kaikkien sen ominaisuuksienkin tulee olla olioita.

Tietorakenteet eli tietotyypit onkin kaikki toteutettu olioina. Niinpä esimerkiksi vektoria tai listaa voi kasvattaa tai kutistaa kulloisenkin olion sisällä vaivaamatta pääohjelmaa. Muita erikoisia tietotyyppejä ovat mm. puu-tyyppi, jolla on aina kaksi oksaa ja yksi juuri, tai graafi, vielä puurakennettakin monipuolisempi joukkotyyppi. Edellä mainittuja ja muita tyyppejä voidaan käyttää mm. erityyppisen tiedon tallennukseen ja helppoon järjestämiseen. Muita tietorakenteita voi luoda omaan tarpeeseen omina olioinaan, jotka sitten voi liittää peräkkäin vaikka vektoriin tai jonoon.

Ohjelmointia helpottaa myös automaattinen roskienkerääjä, joka vapauttaa niiden olioiden varaaman muistin, joihin ei enää ole osoitinta. Tämä tietysti hidastaa ohjelman suoritusta hivenen, mutta toisaalta nopeuttaa valtaisasti sen tekemistä, koska muistivuotoja ei synny. Niiden paikkailuunhan aikaa eniten tuhraantuu koodattaessa ja virheitä korjattaessa.

Eiffelin toteutus

N ykyisissä Eiffel-ympäristöissä Eiffel-koodia ei suinkaan käännetä suoraan konekieleen vaan käyttäen välikielenä C:tä.

Varsinainen ISE:n Eiffel on isojen koneiden kieli. Sen päätarkoitus on "programming in large", siis suurten ohjelmistojen ohjelmointi. Niinpä ISE:n oma Eiffel-paketti on paljon muutakin kuin vain itse kääntäjä. Se on pääasiassa Unix-purkeille tarkoitettu megojen kokoinen kokoelma ohjelmoijan työkaluja, valmiita kirjastoja ja oliokokoelmia mm. graafisen ympäristön luomiseen tai verkkosovellusten ohjelmointiin. ISE:n paketissa on jopa oma kieli, LACE, ACE-tiedostojen eli perinteisemmin "make"-tiedostojen tekemiseen (siis kääntämisen ja linkityksen määrittelyihin).

Sittemmin ISE on alkanut tehdä vastavanlaista pakettia myös PC-yhteensopiviin (pätkitty, mutta toimiva malli on saatavilla ilmaiseksi Maailmanseitistä, osoitteesta http://www.eiffel.com/). On myös olemassa ilmainen, GNU-lisenssillä levitettävä SmallEiffel-kääntäjä, jonka sorsakoodit on valmiiksi sovitettu GNU C -kääntäjiin tusinassa eri laiteympäristössä (ftp://ftp.loria.fr/pub/loria/genielog/SmallEiffel). (Kääntyy pienellä sovituksella myös mm. SAS C:llä.)

Eiffelin esimerkki-ohjelmapätkiä

T ärkein kysymys on tietenkin, millaista on Eiffelin ohjelmakoodi. Se, pitääkö ohjelmoija koodin ulkonäöstä, on vakavampi näkökohta kuin useasti tullaan ajatelleeksikaan. Koodin, siis siistityn koodin, tulee olla ennen kaikkea helppolukuista, jotta se kelpaisi malliksi. Samalla sen tulisi kertoa kielen rakenteesta ja sisäisistä ratkaisuista. Ylempänä kerroin hiukan Eiffelin koodaamistyylistä, mutta mitäpä sanat merkitsisivät ilman konkreettisia esimerkkejä:

1. esimerkki: Hello_World.e

class HELLO_WORLD
   -- Se tutuin ohjelma... Näin merkitään kommentit Eiffelissä!
   -- Usein Eiffelillä ohjelmoidessa laitetaan vain yksi luokka
   -- yhteen tiedostoon ja kerrotaan kääntäjälle, mikä on juuriluokka,
   -- josta suoritus alkaa.
creation make -- Millä rutiinilla olio luodaan, jos ei spesifisesti määrätä
              -- jotakin toista luontioperaatiota.

feature  -- Mitä ominaisuuksia luokalla on. Sekä rutiinit että tietoalkiot.

     make is
          do
             io.put_string("Hello World.") -- io-luokka hoitaa io-toiminnot.
          end

end -- HELLO_WORLD  Ohjelman suoritus päättyy juuriluokan luontioperaation
    -- suorituksen päättymiseen.
2. esimerkki: Rutiinit

V aikkei se välttämätöntä olekaan (siis siihen ei pakoteta), esitetään että rutiineja olisi kahdenlaisia: funktioita ja proseduureja. Funktiot suorittavat jonkin (lasku)toimituksen ja antavat palautteena sen arvon; proseduurit taas eivät palauta mitään, mutta tekevät/muuttavat jotakin tai jonkin muistipaikan arvoa. Ja yksi rutiini tietysti tekee mielellään vain yhden asian. Esimerkki funktion rakenteesta:

nimi(argumentit): TYYPPI is -- otsikko ja palautettavan arvon tyyppi
require                     -- (valinnainen) ehtolauseke argumentin arvon
                            -- sopivuuden testaamiseksi, esim. arg >= 0
local                       -- esitellään muuttujat
     luku: INTEGER
do
                           -- itse rutiini
     Result := mikäliearvo -- funktion palauttama arvo
end                        -- rutiini loppuu ja arvo palautetaan kutsujalle
                           -- vasta end-sanaan tultaessa. rutiinia ei voi
                           -- keskeyttää.
3. esimerkki: toistolauseke

K uten jo aikaisemmin mainittiin, Eiffelissä on perinteisiin kieliin nähden vähän rakenteita kontrollivuon ohjaukseen, mutta ne ovat monipuolisia. Alla on malli Eiffelin toistolausekkeesta, loop-lauseesta:

from       -- from-sanan alle laitetaan toistolauseen alustukseen
           -- tarvittava koodi, esim. muuttujien alkuarvot.
invariant  -- (valinnainen) Ehtolauseke, jonka on oltava voimassa jokaisen
           -- kierroksen alussa, jotta silmukka toimisi oikein (erityisen
           -- tärkeä ensimmäisellä ja viimeisellä kierroksella)
variant    -- (valinnainen) on päinvastainen laskutoimitus kuin se mikä
           -- suoritetaan jokaisella kierroksella; kokonaislukuarvoinen
           -- laskutoimitus, jonka tuloksen täytyy olla positiivinen.
           -- Varmistaa, että suorituskertoja on äärellinen määrä.
until      -- lopetusehto
loop
           -- Tähän väliin itse silmukka.
end
Tuntuiko pitkältä ja hankalalta? Mutta tällaisten juttujen miettiminen etukäteen tekee kummasti debuggauksesta helpompaa ja nopeampaa. Luulisi, että Meyer olisi laittanut toistolauseen loppuun vastaavan toiminnon kuin alun from-lause huolehtimaan toiston jälkeisistä toimenpiteistä. Olisiko unohtanut vai pitänyt turhan hankalana?

Kenelle Eiffel?

H ankala kysymys. Helpompi kai olisi vastata päinvastaiseen: Eiffel ei ainakaan missään nimessä ole perinteisen mallin hakkerin kieli. Eiffel-koodin kanssa ei voi helposti räpeltää tai oikaista. Ohjelman suunnitteluun täytyy uhrata aikaa.

Toisaalta aikaa ei kannata uhrata pienten sovellusten tekemiseen, mutta ammattiohjelmoijille Eiffel voisi olla mannaa. Apuneuvoineen se soveltuu isojen ohjelmien tekemiseen.

Mikään jokapaikan jyrä Eiffel ei ole, mutta ainakin minun suosiostani se kilpailee tasaveroisesti C++:n kanssa (raskaassa sarjassa).


HtmlSaku numero 21, © Copyright 1993-1997 Suomen Amiga-käyttäjät ry.