OCaml
OCaml (ent. Objective Caml) on funktionaalinen olio-ohjelmointikieli. OCaml on laajennettu versio Caml-kielestä ja on sen pääasiallinen implementaatio.
OCamlin ensiversio julkaistiin vuonna 1996 "Objective Caml" -nimisenä, kun "Caml special light" -kieleen yhdistettiin tyypitetty olio- ja luokkamalli. OCaml nimitys otettiin käyttöön vuonna 2011.
OCaml:ssa on korkeatasoinen tulkki ja optimoiva kääntäjä sekä laaja standardikirjasto, joka tekee siitä käyttökelpoisen myös laajojen ohjelmistojen kehitykseen.
OCaml sisältää täysiverisen olio-mallin, vahvan moduulijärjestelmän sekä polymorfisen tyyppijärjestelmän tyypinpäättelyllä. "OCaml System" sisältää teollisuustasoisen toteutuksen, natiivikääntäjät yhdeksälle eri prosessoriarkkitehtuurille, tavukoodikääntäjän, sekä komentorivitulkin (read-eval-loop).
OCamlin jakelu sisältää laajan standardikirjaston, debuggerin, lekseri- ja parseri-generaattorit sekä koodin tulostamiseen ja dokumentointiin tarvittavat osat. OCaml ja sen kirjastot on julkaistu avoimen lähdekoodin lisensseillä (QPL ja GGPL).
OCamlia ei ole standardoitu, vaan kuten esimerkiksi Python, OCamlilla on kielen määrittelevä toteutus, INRIA:n OCaml.
Tyypillinen esimerkkiohjelma "hello.ml" tulostaa sanat "Hello World":
OCamlissa ohjelma käännetään komennolla:
Ohjelman ajaminen:
OCaml on kypsä ML-sukuinen funktionaalinen olio-ohjelmointikieli. Se on kirjoitettu OCamlilla itsellään lukuun ottamatta joitakin C-kielellä kirjoitettuja ajonaikaisia osia. OCaml perii paljon vuosikymmenien funktionaalisten kieliin, kielentutkimukseen ja tyyppiteoriaan liittyvästä akateemisesta tutkimustyöstä. OCamlia käytetään sekä opetuskielenä, että teollisuudessa.
OCaml on staattisesti tyypitetty kieli. Tyyppimäärittelyt ovat valinnaisia: yleensä kääntäjä päättelee arvojen tyypit sen sijaan että ne määriteltäisiin lähdekoodissa. Vahvasti tyypitettynä kielenä se estää muistinhallintavirheitä tehokkaasti.
Tästä seuraten OCaml syntaksi on hälytön, sen kääntäjä poimii virheet tehokkaasti, ja tuloksena syntyvä koodi on nopeaa – OCaml on tehokas kieli.
OCamlissa on ML:stä periytynyt suoraviivainen syntaksi. Sen ytimekäs syntaksi ilmaisee lambda-kalkyylia kolmella tavalla: tunnistimet (esim. "x"), funktiot ("λ x. a") ja sovelmat ("a1 a2"). Lisäksi löytyy "let" -lause (esim "let x = a1 in a2"), jota käytetään sitomaan ilmaisu "a1" tunnistimeen "x" ilmaisussa "a2".
Ocamlissa yksittäinen lauseke on muodoltaan Caml-fraasi. Fraasit ovat joko ilmaisuja tai tunnistimien "let"-määritelmiä. Komentotulkkia käytettäessä ne päättyvät ';;' merkkeihin, jotka eivät ole välttämättömiä kieltä käännettäessä.
Kullekin fraasille lasketaan kääntäjässä arvo ja tyyppi, eikä tyyppiä tarvitse erikseen määritellä.
Tyyppien päättely mahdollistaa "polymorfisuuden" funktioille.
OCamlin tyyppijärjestelmästä löytyvät tyypit totuusarvo (boolean), kokonaisluku, liukuluku, merkki ja merkkijono.
Ennaltamääritellyt tietorakenteet ovat monikko ("tuple"), taulukko ("array") ja lista ("list"). Useimmat OCamlin tietorakenteet ovat muuttumattomia, mutta taulukko on muuttuva - sen kokoa voi muuttaa sen määrittelemisen jälkeenkin. Monikot ja listat voivat sisältää tyypeiltään eriäviä arvoja, kun taulukko sisältää samantyyppisiä arvoja.
OCamlissa ei ole muuttujan käsitettä. OCaml Standard library -kirjasto sisältää viitteet ("references"), yhden alkion taulut joita "let"illä tunnistimiin sitomalla voi viitata vaihteleviin arvoihin.
Käyttäjän määrittelemät tietorakenteet ovat taltiot ("records") ja variantit ("variants"). Taltiot kuvaavat tietorakenteen osaset ja niiden tyypit.
Variantit taasen luettelevat kaikki mahdolliset tyypit määrittelemälleen tietorakenteelle:
OCaml on funktionaalinen ohjelmointikieli – se tukee funktioita matemaattisen määritelmän mukaisesti täysin. Tästä seuraten funktioita voi vapaasti antaa parametreinä ja käyttää kuten muitakin tietotyyppejä. OCaml tukee myös korkeamman asteen funktioita ("higher order functions"), eli funktioita joihin annetaan toisia funktioita argumentteinä.
OCaml tukee rekursiota. Rekursio ilmaistaan käyttäen "rec"-sanaa. Rekursion käyttö on rajoitettu funktioihin, koska sen todistus ei ole eheä mielivaltaisille ilmaisuille.
OCamlin imperatiivisiin ominaisuuksiin kuuluvat "for" ja "while" -silmukat, sekä muuntuvat tietorakenteet kuten taulukot ("array"). Myös taltiot voivat olla muuntuvia, jos ne määritellään käyttämällä avainsanaa "mutable".
OCaml tukee ohjelmien poikkeustilaa ja niiden käsittelyä. Poikkeuskäsittely määritellään "exception" avainsanalla.
OCamlin muistinhallinta on täysin automaattinen - kääntäjä osaa käyttää osoittimia ("pointers") ja ajaa roskienkeräyksen tarvittaessa.
OCaml käyttää moduuleita johdonmukaisen rakenteen ja yhtenäisen nimikäytännön aikaansaamiseksi. OCamlissa tällaisia rakenteita ("structure") määritellään lauseella "struct ... end", jonka sisäpuolella voi olla mielivaltaisia lausekesarjoja. Rakenteelle annetaan yleensä myös nimi sitomalla se tunnistimeen "module" -avainsanalla. Näin estetään nimien loppuminen ja törmäily nimiavaruudessa.
Moduulijärjestelmä mahdollistaa myös tyyppiabstraktion ("abstract types"). Määritellyn tietorakenteen osien näkyvyyttä voi määritellä kuvaajalla"(sic)" ("signature"), joka määritellään avainsanoilla "sig ... end".
OCamlin moduulijärjestelmän avulla voi myös määritellä funktoreita. Funktorit ovat yksinkertaisesti yhden rakenteen avulla parametrisoituja rakenteita; rakenne A joka määritellään rakenteen B:n avulla voidaan sanoa olevan funktori F parametrillä B joka palauttaa rakenteen A. Myös funktoreihin voi soveltaa kuvaajaa ("signature").
OCamlin moduuliominaisuudet mahdollistavat myös monista moduuleista koostuvan ohjelman osien kääntämisen eri aikaan ".ml" rakennetiedostojen ja ".mli" kuvaajien lähdekoodista ".cmo"-objekti- ja ".cmi"-rajapintatiedostoiksi, jotka lopulta yhdistetään konekielikäännökseksi.
OCamlin oliomalli on omintakeinen. OCamlin luokat ("class") määrittelevät olioita ("object") käyttäen periytyvyyttä ja metodeita.
Olioiden tyypitys on tavallinen, ja niillä voi lisäksi olla alatyyppejä. Oliot eivät tunne periytymistä.
Oliot luodaan yleensä luokista, käyttäen "new" -avainsanaa. Oliot voidaan myös luoda kloonaamalla (metodilla "Oo.copy") tai kaappaamalla ("overriding") toisia olioita.
Olioita voidaan myös määritellä ilman luokkia, välittöminä objekteina ("immediate objects"). Tällöin oliota kuvaus ("object ... end") voi esiintyä missä vain ekspressiossa, mutta tuloksena syntyvä olio ei omaa luokkien ominaisuuksia, kuten periytyvyys.
Olioiden sisältämät, niiden luokissa määritellyt tietorakenteet ovat saatavilla vain olioiden metodien kautta (enkapsulaatio). OCaml ei tunne luokkamuuttujia, eli kullakin oliolla on omat yksittäiset tietorakennejoukkonsa. Tässä mielessä OCamlin oliomalli noudattaa klassista olio-ohjelmointi-mallia.
Luokat ovat OCamlissa yleisen olio-ohjelmointi-paradigman mukaisesti määritelmiä olioiden rakentamista varten. OCaml -luokilla on oma, tavallisista tyypeistä poikkeava tyyppijärjestelmänsä, ja luokat voivat periytyä toisista luokista. Luokat määritellään OCamlissa sitomalla luokka ja sen nimi oliorakenteeseen "class NN object ... end" -rakenteella.
Luokkia voidaan periyttää toisista luokista lisäämällä "object ... end"-rakenteen sisään "inherit NN" -viittaus. OCaml tukee moninperiytyvyyttä.
Luokkien metodit määritellään puolestaan samaisen object-rakenteen sisällä "method nn = ..." ilmaisuilla. Luokkien metodimääritelmät ovat varjostavia, eli jälkeläisen metodi korvaa vanhemmalta perityn metodin. Tätä kutsutaan OCamlissa nimellä "late binding". Esi-isä-luokan metodeita voidaan kuitenkin sitoa vaihtoehtoisiin metodinimiin käyttäen avainsanaa "super".
OCaml luokat tukevat niistä olioita luotaessa kutsuttavia alustusmetodeita. Alustusmetodit ovat avainsanalla "initializer" määriteltäviä anonyymejä metodeita, joita ei voi varjostaa tai uudelleenmääritellä. Periytetyissä luokissa alustusmetodit ajetaan määrittelyjärjestyksessä.
OCaml-luokkien metodit voivat olla yksityisiä, jolloin ne eivät näy olion ulkopuolella, ja niitä voidaan kutsua vain toisista saman olion metodeista. Yksityiset metodit määritellään ilmaisulla "method private". OCamlin yksityiset metodit ovat vain saman olio-instanssin käytettävissä, joten ne eroavat tässä suhteessa C++:n yksityisistä metodeista, jotka ovat saman luokan olio-instanssien käytettävissä.
OCaml luokat voivat myös olla virtuaalisia; luokkia joissa määritellään virtuaalisia, sisällöttömiä metodeita ja instanssimuuttujia ("virtual"). Virtuaalisien luokkien virtuaaliset metodit ja muuttujat täytyy määritellä aliluokassa ennen kuin niistä voidaan instantioida olioita.
Virtuaaliset metodit voivat olla yksityisiä, syntaksissa tämä tapaus ilmaistaan "method private virtual".
Tavallisten olio-ohjelmointimallien lisäksi OCaml tukee myös parametrisoituja luokkamääritelmiä, polymorfisia metodeita, tyypinpakotusta ("coercion"), funktionaalisia objekteja (syntaksissa "{< ... >}") ja rekursiivisiä luokkia.