OCaml

Wikipedia
Loikkaa: valikkoon, hakuun
OCaml
Paradigma moniparadigma: imperatiivinen, funktionaalinen, olio-ohjelmointi
Tyypitys staattinen, vahva, pääteltävä
Yleinen suoritusmalli käännettävä
Muistinhallinta roskienkeruu
Julkaistu 1996
Kehittäjä INRIA
Vakaa versio 4.00.1. (5. lokakuuta 2012)
Merkittävimmät toteutukset Ocaml System
Vaikutteet Caml light, Mini ML ja ML
Käyttöjärjestelmä alustariippumaton
Verkkosivu ocaml.org

OCaml (ent. Objective Caml) on funktionaalinen olio-ohjelmointikieli. OCaml on laajennettu versio Caml-kielestä ja on sen pääasiallinen implementaatio.[1]

Historiaa[muokkaa | muokkaa wikitekstiä]

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.[2]

Ominaispiirteet[muokkaa | muokkaa wikitekstiä]

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 modulijä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).[3]

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).[3]

OCamlia ei ole standardoitu, vaan kuten esimerkiksi Python, OCamlilla on kielen määrittelevä toteutus, INRIA:n OCaml.

Esimerkki OCamlin käytöstä[muokkaa | muokkaa wikitekstiä]

Tyypillinen esimerkkiohjelma hello.ml tulostaa sanat "Hello World":[4]

  print_endline "Hello world!";;


OCamlissa ohjelma käännetään komennolla:

  $ ocamlc -o hello_ocaml hello.ml


Ohjelman ajaminen:

  $ ./hello_ocaml
 
  Hello world!


OCaml kielenä[muokkaa | muokkaa wikitekstiä]

OCaml on kypsä ML-sukuinen funktionaalinen olio-ohjelmointikieli. Se on kirjoitettu OCamlilla itsellään lukuunottamatta 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.[5]

Syntaksi[muokkaa | muokkaa wikitekstiä]

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.[6]

Fraasit[muokkaa | muokkaa wikitekstiä]

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ä.[7]

  1 + 2 * 4;;
 
  let piiarvo = 4.0 *. atan 1.0;; (* huomaa oma kertomaoperaattori liukuluvuille *)

Kullekin fraasille lasketaan kääntäjässä arvo ja tyyppi, eikä tyyppiä tarvitse erikseen määritellä.[7]

Tyyppien päättely mahdollistaa polymorfisuuden funktioille.[7]

Tyyppijärjestelmä[muokkaa | muokkaa wikitekstiä]

OCamlin tyyppijärjestelmästä löytyvät tyypit totuusarvo (boolean), kokonaisluku, liukuluku, merkki ja merkkijono.[7]

Tietorakenteet[muokkaa | muokkaa wikitekstiä]

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.[7] 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 letillä tunnistimiin sitomalla voi viitata vaihteleviin arvoihin.[7]

Käyttäjän määrittelemät tietorakenteet ovat taltiot (records) ja variantit (variants). Taltiot kuvaavat tietorakenteen osaset ja niiden tyypit.[7]

(* taltio eli record määritellään murtoluvuille näin: *)
 
type ratio = {num: int; denum: int};;


Variantit taasen luettelevat kaikki mahdolliset tyypit määrittelemälleen tietorakenteelle:[7]

(* variant määritellään numeroille näin: *)
 
  type number = Int of int | Float of float | Error;;

OCaml ja funktiot[muokkaa | muokkaa wikitekstiä]

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ä.[7]

  List.map (function n -> n * 2 + 2) [0;1;2;3;4];;
  - : int list = [2; 4; 6; 8; 10]

Funktiot ja rekursio[muokkaa | muokkaa wikitekstiä]

OCaml tukee rekursiota. Rekursio ilmaistaan käyttäen rec-sanaa. Rekursion käyttö on rajoitettu funktioihin, koska sen todistus ei ole eheä mielivaltaisille ilmaisuille.[8]

 let  rec  f = λ x. a1  in  a2
 
 (** tai esimerkiksi **)
 
 let  rec  f1 = λ x. a1  and  f2 = λ x. a2  in  a

Imperatiiviset piirteet[muokkaa | muokkaa wikitekstiä]

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.[7]

Poikkeukset[muokkaa | muokkaa wikitekstiä]

OCaml tukee ohjelmien poikkeustilaa ja niiden käsittelyä. Poikkeuskäsittely määritellään exception avainsanalla.[7]

Muistinhallinta[muokkaa | muokkaa wikitekstiä]

OCamlin muistinhallinta on täysin automaattinen - kääntäjä osaa käyttää osoittimia (pointers) ja ajaa roskienkeruun tarvittaessa.[7]

OCamlin modulijärjestelmä[muokkaa | muokkaa wikitekstiä]

OCaml käyttää moduleita 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.[9]

 module PrioQueue =  
   struct
     type priority = int
     (** jne... **)
     let extract = function
         Empty -> raise Queue_is_empty
       | Node(prio, elt, _, _) as queue -> (prio, elt, remove_top queue)
   end;;


Modulijä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.[9]

OCamlin modulijä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).[9]

OCamlin moduliominaisuudet mahdollistavat myös monista moduleista 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.[9]

OCamlin oliomalli[muokkaa | muokkaa wikitekstiä]

OCamlin oliomalli on omintakeinen. OCamlin luokat (class) määrittelevät olioita (object) käyttäen periytyvyyttä ja metodeita.

Oliot[muokkaa | muokkaa wikitekstiä]

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[muokkaa | muokkaa wikitekstiä]

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.

Periytyvyys[muokkaa | muokkaa wikitekstiä]

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.

Alustus, näkyvyyden rajoittaminen ja virtuaaliluokat[muokkaa | muokkaa wikitekstiä]

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 ennenkuin niistä voidaan instantioida olioita.

Virtuaaliset metodit voivat olla yksityisiä, syntaksissa tämä tapaus ilmaistaan method private virtual.

Muut luokkaominaisuudet[muokkaa | muokkaa wikitekstiä]

Tavallisten olio-ohjelmointimallien lisäksi OCaml tukee myös parametrisoituja luokkamääritelmiä, polymorfisia metodeita, tyypinpakotusta (coercion), funktionaalisia objekteja (syntaksissa {< ... >}) ja rekursiivisiä luokkia.[10]

Katso myös[muokkaa | muokkaa wikitekstiä]

Lähteet[muokkaa | muokkaa wikitekstiä]

  1. The Caml language (html) © INRIA 1995-2011. All rights reserved.. Viitattu 23.2.2012.
  2. A History of Caml (html) © INRIA 1995-2011. All rights reserved.. Viitattu 23.2.2012.
  3. a b Ocaml (html) © INRIA 1995-2011. All rights reserved.. Viitattu 23.2.2012.
  4. Didier Rémy: First steps in OCaml – Using, Understanding, and Unraveling The OCaml Language (html) Lectures Notes in Computer Science. Copyright © 2000, 2001 by Didier Rémy. Viitattu 23.2.2012. (englanniksi)
  5. http://caml.inria.fr/pub/docs/u3-ocaml/ocaml003.html
  6. Didier Rémy: Core ML – Using, Understanding, and Unraveling The OCaml Language (html) Lectures Notes in Computer Science. Copyright © 2000, 2001 by Didier Rémy. Viitattu 23.2.2012. (englanniksi)
  7. a b c d e f g h i j k l Xavier Leroy, Damien Doligez, Alain Frisch, Jacques Garrigue, Didier Rémy and Jérôme Vouillon: Standalone Caml programs, The OCaml system release 3.12 July 29, 2011. Copyright © 2008 Institut National de Recherche en Informatique et en Automatique. Viitattu 23.2.2012. (englanniksi)
  8. Didier Rémy: 1.5. Recursion, Core ML – Using, Understanding, and Unraveling The OCaml Language (html) Lectures Notes in Computer Science. Copyright © 2000, 2001 by Didier Rémy. Viitattu 27.2.2012. (englanniksi)
  9. a b c d Didier Rémy: First steps in OCaml – Using, Understanding, and Unraveling The OCaml Language (html) Lectures Notes in Computer Science. Copyright © 2000, 2001 by Didier Rémy. Viitattu 23.2.2012.
  10. Didier Rémy: The object layer – Using, Understanding, and Unraveling The OCaml Language (html) Lectures Notes in Computer Science. Copyright © 2000, 2001 by Didier Rémy. Viitattu 29.2.2012.