Koka Ryhmä 11 Juuso Tapaninen, Akseli Karvinen 1. Taustoja 2. Kielen filosofia ja paradigmat 3. Kielen syntaksia ja vertailua JavaScriptiin Lähteet 1
1. Taustoja Koka on Daan Leijenin ja Microsoft:n kehittämä funktionaalinen ohjelmointikieli, jossa puhtaat funktiot ja sivuvaikutukselliset ohjelman osat voidaan erotella selkeästi toisistaan, ja jossa jokaisen funktion vaikutukset voidaan päätellä automaattisesti. Kielen ydin on pieni ja syntaksiltaan se muistuttaa JavaScriptiä. [2] Kokassa tyypit ovat yksi tärkeä osa kielen kokonaisuutta, mutta tyypit eivät kerro funktion toiminnallisuudesta kaikkea. Esimerkiksi kokonaislukuja parametrinaan ottava ja palauttava funktio voi selkeästä tyypityksestään huolimatta aiheuttaa sen käyttäjälle tuntemattomia sivuvaikutuksia. Tästä syystä Kokassa funktion eri vaikutukset huomioidaan kielen tyyppijärjestelmässä. [1] Koka on toistaiseksi vielä kehitys ja tutkimusvaiheessa oleva ohjelmointikieli: Koka projektin tavoitteena on selvittää, voidaanko vaikutusten päättelyä käyttää ohjelmoinnissa laajemmin. Toistaiseksi Kokalla on toteutettu vain pieniä ja keskisuuria projekteja, mikä johtunee osittain siitä, että kieli on kehitysvaiheessa ja sen ympärille ei ole vielä muodostunut aktiivista kehittäjäyhteisöä. Käännettyä Koka koodia voidaan tällä hetkellä ajaa joko NodeJS:llä tai selaimessa. [2] 2. Kielen filosofia ja paradigmat Koka kielen keskeisimpiä suunnitteluperiaatteita on tilallisen ja puhtaan toiminnallisuuden selkeä erottaminen. Tämä käy parhaiten ilmi kielen tyyppijärjestelmästä, joka ottaa huomioon funktioiden eri vaikutukset ja sisällyttää ne osaksi funktion tyyppikuvausta. Toisaalta tyyppijärjestelmästä on pyritty tekemään myös mahdollisimman yksinkertainen kehittäjän kannalta ja Koka päättelee suurimman osan tyypeistä itse: esimerkiksi paikallisille muuttujille ei tarvitse koskaan määrittää eksplisiittisesti niiden tyyppiä [4]. Kokaa kuvataan sen sivuilla funktionaalisesti suuntautuneeksi kieleksi; käytännössä Koka on paradigmaltaan funktionaalinen ja imperatiivinen [2]. Kokan tyyppijärjestelmä tekee selkeän jaottelun puhtaasti funktionaalisten ja sivuvaikutuksellisten osien välille, mikä tekee esimerkiksi muunnettavan tilan hyödyntämisestä kehittäjälle helppoa sellaisissa kohdissa, joissa sen käyttö on tarpeen tai muuten tilanteeseen sopivaa. Syntaksiltaan Koka muistuttaa paljolti JavaScriptiä ja siten myös muita tulkattavia kieliä, mutta on kuitenkin käännettävä kieli. Semanttisesti se pyrkii olemaan hyvin vapaamuotoinen. Kuten esimerkiksi Haskellissa, Go:ssa tai Pythonissa, Koka puolipisteet asetetaan automaattisesti oikeisiin kohtiin, jolloin kehittäjän ei ole pakko käyttää niitä (mutta voi myös niin halutessaan käyttää puolipisteitä) [3]. Myös if else rakenteiden aaltosulkeet voidaan jättää merkitsemättä ja Kokassa funktion viimeinen rivi palautetaan implisiittisesti, joskin myös nämä voi niin halutessaan kirjoittaa itse. Vaikka Koka kykenee implisiittisesti selvittämään useimpien muuttujien ja funktion argumenttien tyypit, kuuluu hyviin 2
ohjelmointitapoihin funktion argumenttien ja paluuarvon tyyppien merkkaaminen. Tämä auttaa itse kehitystyötä (dokumentoi funktion toiminnallisuutta) ja auttaa kääntäjää päättelemään tyyppejä automaattisesti. Tällä hetkellä Kokaa voidaan kääntää JavaScript koodiksi, jota voidaan ajaa NodeJS:llä tai selaimessa. Kokan kääntäjä on toteutettu Haskell:lla. Funktion eri sivuvaikutukset ovat osa Kokan tyyppijärjestelmää. Kokassa funktiolla voi olla useita eri vaikutuksia ja nämä vaikutukset on nimetty seuraavasti: total, exn, div, ndet, alloc<h>, read<h>, write<h> ja io. Total ei ole mikään varsinainen vaikutus, vaan tarkoittaa lähinnä sitä, että funktiolla ei ole mitään sivuvaikutuksia. exn tarkoittaa, että funktio voi aiheuttaa poikkeuksen, div (divergent) merkitsee rekursiivista funktiota ndet:n tarkoittaessa epädeterminististä funktiota. alloc<h>, read<h> ja write<h> vaikutukset viittaavat tilallisiin funktioihin, jotka käsittelevät kekoa h. io vaikutus merkitsee funktion tekevän mitä tahansa siirräntää (input/output). Funtiolle voidaan määrittää sen vaikutus joko eksplisiittisesti kehittäjän toimesta, tai se voidaan päätellä kääntäjän avulla implisiittisesti. [1] Funktiolla voi olla useita eri sivuvaikutuksia yhtäaikaisesti, ja joillekin näille yhdistelmille on Kokassa omat erilliset lyhenteensä. Näistä kiinnostavimmat lienee pure, joka on exn ja div:n yhdistelmä ja vastaa Haskellin käsitystä puhtaasta funktiosta, sekä io, joka voi olla yhdistelmä kaikkia eri vaikutuksia ja on siten pahin Kokassa määritellyistä vaikutuksista. Funktioiden sivuvaikutukset voidaan tyyppien tapaan päätellä kääntäjän toimesta, mutta usein vaikutukset merkataan funktion paluutyyppikuvaukseen total vaikutustua lukuunottamatta. Jos funktion vaikutus ei ole oleellinen, voidaan sen tyypiksi myös merkata _e, joka tarkoittaa jokerimerkkiä ja vastaa mitä tahansa kääntäjän päättelemää tyyppiä. Kokan kääntäjä hyödyntää vaikutusten yhdistelmien päättelyssä rivipolymorphismia. Kokassa tyyppijärjestelmässä mukana oleva vaikutus ei ole vain kääntäjän hyödyntämää ylimääräistä tyyppitietoa: Koka funktion tyypin (argumentit, paluuarvo ja vaikutus) avulla voidaan formaalisti todistaa funktion toiminnallisuus. Esimerkiksi funktion, jolla ei ole exn vaikutusta, on matemaattisesti mahdotonta heittää poikkeusta. Muunnettavaa tilaa käsitellään Kokassa viitteiden kautta. Viitteet ovat tyyppiä ref<h, _>, joka tarkoittaa viitettä muunnettavaan arvoon, joka on tyyppiä _ (esimerkiksi int, string tms.) jossain keossa h. Kekoihin liittyvät vaikutukset alloc<h>, read<h> ja write<h> voidaan yhdistää tilallisen vaikutuksen, st<h>, alle. Vaikka funktion sisällä tapahtuisi tilallisia vaikutuksia, ei sen tyypistä välttämättä tule tilallinen: tilallinen st<h> vaikutus voidaan jättää huomiotta, jos kekoon h ei voida viitata funktion ulkopuolella, eli jos keko ei ole osa argumentti tai paluutyyppiä [4]. Perustietotyyppien lisäksi Kokassa voidaan luoda omia tyyppejä. Type sanalla luodut tyypit ovat algebrallisia tietotyyppejä, ts. niiden mahdollisille arvoille on useita eri vaihtoehtoja. Esimerkiksi yksinkertainen enumeraatiotyyppi voidaan luoda kirjoittamalla typevarit{ Sininen;Punainen;Vihrea. Tyypin vaihtoehtojen rakentajille voidaan myös antaa parametreja. Rakentajien nimetyille parametreille luodaan myös automaattisesti funktiot, joilla parametrin arvo voidaan noutaa tyypin instanssista. Kokan tyypit ovat oletuksena 3
muuttumattomia, jolloin tyyppien arvon muuttaminen palauttaa aina uuden tyypin instanssin muutetun arvon kera. 3. Kielen syntaksia ja vertailua JavaScriptiin Syntaksiltaan kieli muistuttaa hyvin pitkälti JavaScriptiä. Yksinkertainen neliöjuurifunktio Kokalla voitaisiin kirjoittaa seuraavasti: function(x:int):totalint { x*x JavaScriptistä poiketen Kokassa voidaan määrittää parametrien tyypit sekä funktion paluutyyppi ja mahdolliset sivuvaikutukset. Myös funktion viimeinen rivi palautetaan implisiittisesti, joten return:n käyttö ei ole pakollista. Kokan tavoin myös JavaScript voi tarvittaessa asettaa puolipisteet automaattisesti, mutta tämä voi johtaa ongelmiin tietyissä tilanteissa, minkä vuoksi monet tyylioppaat pakottavat puolipisteiden kirjoittamisen. Koka tarjoaa ohjelmoijalle paljon erilaista syntaktista sokeria. Esimerkiksi merkkijonomuuttujalle s voitaisiin kutsua jotain merkkijonoa parametrinaan hyväksyvää funktiota joko muodossa s.funktiokutsu(mahdollinenparametri) tai funktiokutsu(s,mahdollinenparametri), joista kääntäjä muuntaa edeltävän muodon jälkimmäiseen kehittäjän puolesta. Pistenotaatiolla voidaan myös ketjuttaa useampia funktiokutsuja peräkkäin yksinkertaisesti, esimerkiksi merkkijonon pituuden voisi tulostaa seuraavasti: s.length.println. Tyypit ovat ehkä suurin ero JavaScriptin ja Kokan välillä, sillä JavaScript on täysin dynaamisesti tyypitetty kieli, siinä missä Koka on staattisesti tyypitetty. JavaScriptiä voi ohjelmoida Kokan kaltaisesti funktionaalisella paradigmalla, mutta JavaScriptin puolella on yleistä myös olio pohjainen ohjelmointityyli, jota myös useat JavaScriptin sisäiset toiminnallisuudet hyödyntävät (esimerkiksi Math, Object ja String). Kokassa kaikki tietorakenteet ovat oletuksena muuttumattomia, joskin viiteiden avulla Kokassakin voidaan hyödyntää muunneltavia tyyppejä. Esimerkki viitteitä hyödyntävästä fibonaccista: 4
funfibonacci(n:int):pureint { varx:=0 vary:=1 repeat(n){ y0=y y:=x+y x:=y0 x Esimerkissä esiintyvä var on jälleen Kokan kääntäjän tarjoamaa syntaktista sokeria, joka tarkoittaa samaa kuin valx:=ref(0). Viitattu arvo saadaan viitteestä ulos! operaattorilla ja viitteen arvoa muutetaan := operaattorilla, siinä missä muuttumattoman operaattorin arvo asetettaisiin tavallisella yhtäsuuruus (=) merkillä. JavaScriptissä ei ole minkäänlaisia muuttumattomia arvoja ja kaikki arvot on oletuksena muunneltavia. JavaScriptiin on tosin olemassa kirjastoja, kuten Immutable.js [5], jotka pyrkivät tuomaan muuttumattomat tietorakenteet myös JavaScriptin puolelle. Mitään kielitason toteutuksia muuttumattomille tietorakenteille ei kuitenkaan ole JavaScriptissä vielä olemassa. Kokasta löytyy kolmea looppirakennetta: perinteinen for loop, jolle annetaan iteraattorifunktio ( for(1,10)fun(i){println(i) ), repeat loop, joka toimii for loopin tapaan, mutta siitä puuttuu iteraattorifunktio ( repeat(10){println( HelloWorld ) ) sekä perinteinen while loop: fun() { var i := 10 while { i >= 0 { println(i) i := i - 1 JavaScriptin ja Kokan yhtäläisyydet loppuvat samankaltaisen syntaksin ja yhteisen alustan (Kokan nykyinen kääntäjä voi tuottaa selaimessa ajettavaa JavaScriptiä) jälkeen hyvin nopeasti. Siinä missä Koka pyrkii olemaan mahdollisimman funktionaalinen ja puhdas, ei JavaScript pakota kehittäjää mihinkään tiettyyn paradigmaan. Vaikka JavaScriptillä voidaan ohjelmoida sekä funktionaalisesti että olio-pohjaisesti, ei se tarjoa kielitasolla kummallekkaan paradigmalle kovinkaan hyviä työkaluja. 5
Lähteet [1] Leijen, Daan. "Koka: Programming with row polymorphic effect types." http://research.microsoft.com/pubs/210640/paper.pdf (2014). [2] Koka Microsoft Research http://research.microsoft.com/en us/projects/koka/ [3] Koka language specification http://research.microsoft.com/en us/um/people/daan/koka/doc/kokaspec.html [4] rise4fun Interactive Koka tutorial http://www.rise4fun.com/koka/tutorial [5] Immutable.js https://facebook.github.io/immutable js/ 6