fix e e (fix e). fix = λf.(λx.f (x x)) (λx.f (x x)) (9)

Koko: px
Aloita esitys sivulta:

Download "fix e e (fix e). fix = λf.(λx.f (x x)) (λx.f (x x)) (9)"

Transkriptio

1 Käytännön funktionaaliset ohjelmointikielet esittävät rekursion tällä tavalla. Teorian näkökulmasta olisi kuitenkin eleganttia, jos oikean puolen Termissä ei tarvittaisi vasemman puolen Muuttujannimeä, koska silloin koko määritelmä olisi yksinkertainen kuin sanakirjassa. Tämä voidaan tehdä lisäämällä kieleen Y- eli kiintopistekombinaattori (fixpoint / fixed-point combinator) ja sille δ-reduktiosääntö. Esimerkiksi normaalin sievennysjärjestyksen kielessä se on fix e e (fix e). Se voitaisiin jopa määritellä ilman rekursiota fix = λf.(λx.f (x x)) (λx.f (x x)) (9) joskin tämän määritelmän muoto riippuu normalisointijärjestyksestä. Esimerkiksi kertomafunktio (8) saisi muodon Tyypitys fact = fix (λf.λn. if (n > 1) (n f (n 1)) 1) jossa uusi parametri f saa arvokseen factin oikean puolen. Nämä δ-reduktiot tuovat kuitenkin mukanaan sen, että enää ei aina tiedetäkään, miten voitaisiin jatkaa normalisointia: Jos redeksinä löydetään vaikkapa 6 + Z True niin sille ei olekaan vastaavaa oikeaa puolta. Ohjelmoija sanoisi, että silloin ohjelmassa on tyyppivirhe koska siinä yritetään soveltaa alkeisoperaatiota vääränlaiseen argumenttiin. Alun perin tyyppiteoriaa (type theory) kehitettiin matemaattisessa logiikassa torjumaan sellaisia itseensä viittaavia ilmauksia kuten valehtelijan paradoksi Tämä lause ei ole totta! joille ei voi antaa loogista tulkintaa. Tietojenkäsittelijät puolestaan soveltavat tyyppiteoriaa tyyppivirheiden käsittelyyn ohjelmointikielissä, joissa itseensä viittaaminen eli rekursio on välttämätöntä. Ohjelmointikielessä voi olla dynaaminen tyypitys, jolloin ohjelman suoritus keskeytyy suoritusaikaiseen tyyppivirheeseen, jos se päätyy tilanteeseen, jota ei osatakaan normalisoida. staattinen tyypitys, jolloin kielen toteutus tutkii etukäteen ohjelman lähdekoodin, ja yrittää varmistua, ettei sen suoritus voi johtaa tyyppivirheisiin. Ohjelma hyväksytään suoritettavaksi vain jos tämä pystytään varmistamaan hylätään jos ei pystytä, ja ohjelmoijalle raportoidaan käännösaikainen tyypitysvirhe. Ohjelmoijan näkökulmasta dynaaminen tyypitys on joustavampaa kuin staattinen 17

2 staattinen tyypitys vähentää debuggauksen vaatimaa vaivaa, koska se karsii osan ohjelmointivirheistä jo ohjelmaa kirjoitettaessa. Staattinen tyypitys jakautuu vielä tyypintarkistukseen (typechecking) jossa ohjelmoija ilmoittaa koodissaan käyttämiensä muuttujien tyypit, ja kielen toteutus tarkastaa, että ne ovat oikein. Esimerkiksi kertomafunktiossa (8) ohjelmoija ilmoittaisi, että sen tyyppi on Z Z eli funktio, jonka parametri on tyyppiä Z ja tulos tyyppiä Z. Useimmat staattisesti tyypitetyt ohjelmointikelet käyttävät tyypintarkistusta. tyypinpäättelyyn (type inference) jossa ohjelmoijan ei tarvitse ilmoittaa muuttujiensa tyyppejä, vaan toteutus päättelee ne käyttöyhteyden perusteella. Esimerkiksi kertomafunktiossa (8) tämä päättely voisi edetä seuraavasti: 1 Koska fact alkaa λn niin sen pitää olla jotakin funktiotyyppiä t u. 2 Koska parametristä n vähennetään 1 Z niin myös sen tyypin t pitää olla Z. 3 Koska tuloksena voi olla 1 Z niin myös sen tyypin u pitää olla Z. Tällaiset menetelmät pohjautuvat logiikkaan. LAP-kurssin muistiinpanoissa mainittiin seuraava tulos: Lause 4 (Ricen lause). Jokainen Turingin koneiden epätriviaali semanttinen ongelma on ratkeamaton. Lauseen 2 perusteella sama pätee myös λ-laskennalla kirjoitetuille ohjelmille. Koska on epätriviaali semanttinen ongelma varmistaa voiko annettu ohjelmakoodi päätyä tyyppivirheeseen vaiko ei, niin tarkka tyypinpäättely on ratkeamatonta eli sellaisen ohjelmointikielen toteutus mahdotonta. Siksi tyypinpäättely on turvallisesti epätarkkaa: Ohjelmakoodi hyväksytään suoritettavaksi vain jos ohjelmointikielen toteutus on pystynyt varmistumaan että tyyppivirheet ovat mahdottomia. Tätä epätarkkuutta on vähennetty ohjelmointikielten tutkimuksessa ja kehityksessä vaihe vaiheelta määrittelemällä niille yhä ilmaisuvoimaisempia tyyppijärjestelmiä. Tällä kurssilla ja Haskell-kielessä sitoudutaan seuraavaan täsmällisen tyypityksen periaatteeseen: Jokaisella muuttujalla on täsmälleen yksi tarkka tyyppi, ja se määrätään staattisesti. Matematiikassa ei noudateta tätä periaatetta aivan orjallisesti: 1 Esimerkiksi jokainen luonnollinen luku m N kuuluu myös kokonaislukutyyppiin Z, ja 2 kaikki ne kuuluvat puolestaan rationaalilukutyyppiin Q, ja 3 kaikki ne kuuluvat puolestaan reaalilukutyyppiin R, ja 4 kaikki ne kuuluvat puolestaan kompleksilukutyyppiin C. Samaan tapaan olio-ohjelmoinnissa luokan L jäsenet ovat samalla myös sen jokaisen yliluokan jäseniä. 18

3 3 Funktionaalisen ohjelmoinnin historiaa 1934 Kurt Gödel aloitti rekursiivisten funktioiden ja relaatioiden teorian. Se oli osa hänen kuuluisan epätäydellisyyslauseensa todistusta. Se oli ensimmäinen ehdotus arkikielen käsitteen mekaanisesti laskettava tarkaksi määritelmäksi. Se oli kuitenkin puhtaan looginen fomalismi, jolloin sen mekaanisuus ei ollut aivan ilmiselvää muille kuin matemaatikoille kehitettiin (toisistaan riippumatta) 2 sen selkeämmin mekaanista muotoilua: Alan Turing esitteli nimeään kantavat koneet. Alonzo Church esitteli λ-laskennan, jota käsittelimme luvussa 2. Siten funktionaalinen ohjelmointi oli läsnä jo silloin, kun teoreettinen tietojenkäsittelytiede otti ensiaskeleensa määriteltiin 2 vanhinta yhä käytössä olevaa ohjelmointikieltä: Fortran (Formula translator) josta tuli pitkäksi aikaa tieteellisen laskennan eli numeronmurskauksen valtakieli. Lisp (List processing) josta tuli pitkäksi aikaa tekoälytutukimuksen valtakieli. Se lainasi λ-laskennan ideoita. Siinä on dynaaminen tyypitys. Siten funktionaalinen ohjelmointi oli läsnä jo modernien ohjelmointikielten syntyessä välillä tyyppiteoriaa (jonka tutkimus oli alkanut jo 1900-luvun alussa) kehitettiin edelleen, aluksi loogikkojen ja myöhemmin myös tietojenkäsittelijöiden toimesta. Tämän tutkimuksen keskeinen tuotos oli Hindley-Milner- eli HM-tyyppiteoria, johon useimmat nykyiset tyypinpäättelevät ohjelmointikielet pohjautuvat. Tietojenkäsittelijä Robin Milner keksi itsenäisesti uudelleen saman teorian, jota loogikko J. Roger Hindley oli tutkinut aiemmin. Alkuperäisen idean olivat keksineet logiikassa jo Churchin oppilas Haskell B. Curry ja Robert Feys. Sekä ohjelmointikieli Haskell että kuritus (jonka tosin keksi toinen loogikko Moses Schönfinkel) on nimetty Curryn mukaan luvun alussa funktionaalisten ohjelmointikielten kehitys oli edennyt standardointivaiheeseen saakka: Dynaamisesti tyypitetty Common Lisp -kieli sai lopullisen standardinsa (Steele, 1990). (Saman kieliperheen yhä kehittyviä kieliä ovat mm. Scheme ja Clojure.) HM-tyypinpäättelevän ahkeran kielen Standard ML (SML) ensimmäinen standardi ilmestyi. 19

4 HM-tyypinpäättelevän kielemme Haskell ensimmäinen standardi ilmestyi. Standardi määrittelee, että Haskell-kielen suoritustapa on rento. Haskell-kielen toteutukset ovat laiskoja, vaikka standardi ei sitä tarkkaan ottaen vaadikaan. Siksi Haskell-kieltäkin on tapana kutsua laiskaksi luvun lopussa myös näiden HM-tyypinpäättelevien kielten standardointi oli edistynyt: SML 97 (Milner et al., 1997) on SML-kielen lopulliseksi tarkoitettu standardi. (Samaan kieliperheeseen kuuluvat mm. OCaml ja F#.) Haskell 98 (Peyton Jones, 2003) on Haskell-kielen merkittävä standardi luvulla kiinnostus erityisesti Haskell-kieleen on kasvanut. Sillä on rentona kielenä monia kauniita teoreettisia ominaisuuksia. Onko niistä hyötyä käytännön ohjelmoinnissa vai haittaa? Sen laajennettu HM-tyypinpäättely on yhdistänyt parametrisen ja ad hoc - monimuotoisuuden. Tälle yhdistelmälle on löytynyt monia yllättäviä käyttökohteita ohjelmoinnissa. Tällä hetkellä uusin standardi on Haskell 2010 (Marlow, 2010). 4 Haskell-kieliset ohjelmat Tällä kurssilla tutustutaan funktionaaliseen ohjelmointikieleen Haskell. Sen kotisivu on josta löytyy standardi- ja muuta materiaalia, toteutuksia, kirjastoja,... Haskell-oppikirjoja on sekä painettuna (Hutton, 2007; Thompson, 2011) että verkossa (Lipovačka, 2011; O Sullivan et al., 2008). Haskell on puhdas (pure) funktionaalinen kieli, eli siinä ei ole lainkaan sivuvaikutuksia. Jos Haskell hyväksyy lähdekoodisi ilman virheilmoituksia, niin koodisi on varmasti funktionaalista. Puhtaus ja laiskuus ovat yhteydessä toisiinsa: epäpuhtaassa laiskassa kielessä ei tiedettäisi milloin eri sivuvaikutukset tapahtuisivat. Haskell onkin varsin uskollinen (rennolle laiskalle) λ-laskennalle. Keskitymme aluksi Haskellin suorituspuoleen ja syvennämme myöhemmin sen tyypityspuolen kuvausta. Käytämme Haskell Platform -pakettia, jonka voi asentaa kielen kotisivulta, ja jossa on kääntäjä ghc (eli Glasgow Haskell Compiler). 20

5 lauseke tuottaa omaa arvo omaa tyyppi on osa sopii omaa hahmo Kuva 1: Jokainen arvo, lauseke, ja hahmo omaa tietyn tyypin. tulkki ghci (eli ghc interactive) jota käytämme pääosan kurssista. Sen keskeisiä komentoja ovat :load tiedosto joka lataa Haskell-lähdekoodia. :type lauseke joka ilmoittaa päätellyn tyypin. kirjastot jotka laajentavat Haskell-standardin peruskirjastoja merkittävästi uusilla tietotyypeillä ja funktioilla. Paketin lisäksi kannattaa hankkia jokin editori, joka ymmärtää Haskell-syntaksia. Haskell-koodin merkitys voi riippua siitä, kuinka se on sisennetty. Yliopiston Windows-koneissa sellainen on Notepad++. Luennoija suosii itse Emacs-editorin Haskell-moodia. Esittelemme rinnakkain 4 käsitettä: Arvot jotka ovat laskennan tuloksia. Tyypit koska jokaisella arvolla on yksi tietty tyyppi. Lausekkeet jotka tuottavat arvoja. Lausekkeen tyyppi kertoo, minkä tyyppisiä arvoja se voi tuottaa. Hahmot (patterns) joita käytetään lausekkeissa sopimaan (match) arvoihin. Hahmon tyyppi kertoo, minkä tyyppisiin arvoihin se sopii. Kuva 1 esittää niiden väliset suhteen. 4.1 Syntaksista Muuttujien nimet alkavat pienellä kirjaimella, ja jatkuvat kirjaimilla, numeroilla, alaviivoilla _ ja heittomerkeillä. Muut nimet (kuten tyyppien, konstruktorien ja modulien nimet) ovat muuten samanlaisia, mutta ne alkavatkin SUURELLA kirjaimella. Haskellissa saa käyttää samaa nimeä eri tarkoituksiin, kun ne eivät voi mennä sekaisin: Esimerkiksi tyypin nimi voi olla sama kuin konstruktorin nimi, koska tyypit ja konstruktorit eivät voi esiintyä samassa osassa koodia. 21

6 x y tarkoittaa == x on sama kuin y /= x ei ole sama kuin y < x on pienempi kuin y > x on pienempi kuin y <= x on pienempi tai yhtäsuuri kuin y >= x on suurempi tai yhtäsuuri kuin y + lukujen yhteenlasku, - vähennuslasku, * kertolasku, / jakolasku ja ˆ potenssiinkorotus && x ja y x tai y ++ listojen x ja y yhdistäminen peräkkäin. yhdistetty funktio x y $ Oikealle assosioiva heikommin kuin sitova funktionkutsuoperaattori. Siis x $ y $ z u on x (y (z u)). Taulukko 1: Haskell-kielen valmiiksi määriteltyjä operaattoreita. Lisäksi muuttujan nimi voi koostua pelkästään erikoismerkeistä, jolloin se tulkitaan binääriseksi operaattoriksi, eli 2-parametriseksi funktioksi, joka kirjoitetaankin niiden väliin. Taulukossa 1 on yleisimmät valmiiksi määritellyt operaattorit. Jos on operaattori, niin (x ) on funktio λy.x y eli jolle on annettu vain sen 1. argumentti x ( y) on funktio λx.x y eli jolle on annettu vain sen 2. argumentti y ( ) on funktio λx.λy.x y eli ilman kumpaakaan sen argumenttia, eli tavallisena niiden eteen kirjoitettavana funktiona. Siis x y on sama kuin ( ) x y. Kääntäen, tavallisesta nimestä saa operaattorin ympäröimällä se takaperoisilla lainausmerkeillä.... Siis x f y on sama kuin f x y. Operaattoreille voi määritellä assosiaatiosuunnan ja sidontavoiman infixp q jossa p on l(eft, vasemmalle) tai r(ight, oikealle) tai puuttuu (ei assosioidu) oletusarvo on l q on sidontavahvuus 0 q 9 heikoimmasta vahvimpaan oletusarvo on 9. Kommentteja on kolmenlaisia: Merkkiyhdistelmä -- aloittaa kommentin, joka jatkuu tämän rivin loppuun saakka. 22

7 Merkkiyhdistelmien {- -} välinen teksti on kommenttia. Nämä kommentit voivat olla sisäkkäin, joten niillä voi kommentoida lähdekoodia pois. Merkkiyhdistelmien {-# #-} välinen teksti on erikoiskommentti, johon voi laittaa Haskell-toteutukselle ohjeita (pragmas). Tällä kurssilla tärkein niistä on lähdekooditiedoston alkuun sijoitettava {-# LANGUAGE laajennus_1,laajennus_2,... #-} jolla voi kääntää päälle haluamansa laajennukset standardikieleen ja käyttää niitä tässä lähdekooditiedostossa. Jos yrittää käyttää jotakin laajennusta kääntämättä sitä ensin päälle, niin ghci ilmoittaa asiasta. 4.2 Atomiset perustietotyypit Haskell δ-määrittelee joitakin atomisia perustietotyyppejä operaatioineen. Tyypin rakenteisuus tarkoittaa, että tyypin arvot sisältävät pienempiä osia, joilla on omat arvonsa esimerkiksi tietue sisältää kenttiä, joilla on omat sisältönsä atomisuus tarkoittaa, että tyypin arvoja ei voi jakaa tällä tavoin pienempiin rakenneosiinsa. Näiden atomisten tyyppien vakiot ovat samalla lausekkeita jotka tuottavat vastaavan arvon siis lukuvakio 123 tuottaa lukuarvon 123 ja niin edelleen hahmoja jotka sopivat siihen arvoon Totuusarvotyyppi Totuusarvotyypin nimi on Bool. Sen vakiot ovat False and True. Lausekkeessa if ehto then tulos_t else tulos_f ehto on tyyppiä Bool sen kumpikin tuloshaara tulos_t ja tulos_f on keskenään samaa tyyppiä t tämä tyyppi t on samalla koko if-lausekkeen tyyppi koska kaikki sen tuottamat arvot ovat sitä tyyppiä. else-haaraa ei voi jättää pois mikä arvo silloin tuotettaisiin, jos ehto on False? 23

8 4.2.2 Merkkityyppi Haskell käyttää Unicode-merkistöä. Merkkityypin nimi on Char. Merkkivakio kirjoitetaan yksinkertaisten lainausmerkkkien... väliin. Merkkivakioiden kirjoitusasu (Marlow, 2010, luku 2.6) on ohjelmointikielen C käyttämän kirjoitusasun laajennus. Haskell käsittelee merkkijonoja merkkilistoina Kokonaislukutyypit Haskell sisältää valmiina tyypit Integer matemaatikon mielivaltaisen kokoisille kokonaisluvuille Z. Niissä bittien lukumäärää rajoittaa vain vapaa muisti. Aritmetiikka on hidasta, koska se on toteutettu ohjelmallisesti. Int ohjelmoijan kokonaisluvuille, joiden bittien lukumäärä on toteutuksen luonnollinen sananpituus. Se on tyypillisesti 32 tai 64 bittiä, Haskell-toteutuksesta riippuen. Haskell-standardi sallii sen, että toteutus voi varata muutaman biteistä omaan sisäiseen kirjanpitoonsa, joten bittien määrä voikin olla esimerkiksi vain 30. Aritmetiikka on nopeaa, koska se on toteutettu konekäskyillä. Aritmetiikka pyörähtää ympäri hiljaisesti kun luku ei enää mahdu tähän maksimipituuteen. Kirjastossa Data.Int on tyypit Intb joilla voi antaa etumerkillisen kokonaisluvun bittien määrän b = 8, 16, 32, 64 tarkasti. Kirjastossa Data.Word on vastaavat tyypit Wordb etumerkittömille kokonaisluvuille tyyppi Word joka on etumerkitön vastine tyypille Int. Kirjastossa Data.Ratio on tyyppi Rational matemaatikon murtoluvuille Q. välineet joilla voi määritellä tyyppien Intb perusteella sellaiset ohjelmoijan murtoluvut, joissa on haluttu määrä bittejä Liukulukutyypit Haskell sisältää valmiina IEEE-standardin mukaiset tyypit Real yksin- ja Double kaksinkertaisen tarkkuuden liukuluvuille. Epätarkkuutensa vuoksi yksinkertaista tarkkuutta kannattaa käyttää vain silloin jos kaksinkertainen kuluttaisi liikaa muistia. Kirjastossa Data.Complex on välineet, joilla voi määritellä kompleksiluvut C näiden tyyppien perusteella. 24

9 4.3 Funktiot Tyyppi funktio, jonka argumentti on tyyppiä t ja tulos on tyyppiä u kirjoitetaan t -> u. Tämä -> on tyyppikonstruktori: Funktio, joka ottaa parametreinaan tyypit t ja u, ja tuottaa niistä tuloksenaan tyypin t -> u. Tämä tyyppikonstruktori -> assosioi oikealle, joten 2-parametrisen kuritetun funktion tyyppi t -> (u -> v) eli funktio, joka ottaa argumentin tyyppiä t ja palauttaa funktion, joka ottaa argumentin tyyppiä u ja palauttaa tuloksen tyyppiä v voidaan kirjoittaa ilman sulkuja t -> u -> v ja niin edelleen. Funktiotyypit ovat atomisia. Funktiotyypeillä ei ole omia hahmoja. λ-abstraktio λx.e kirjoitetaan lausekkeena \ x -> e. Lauseke \ x y -> e on lyhenne lausekkeelle \ x -> \ y -> e ja niin edelleen. Ohjelmoija voi esitellä uuden muuttujan haluamaansa Tyyppiä ja määritellä sille arvon lauseke seuraavasti: muuttuja :: Tyyppi muuttuja = lauseke Tavallisesti ohjelmoija on määrittelemässä uutta funktiota, jonka nimeksi annetaan muuttuja, eli muuttuja :: ParametrinTyyppi -> TuloksenTyyppi muuttuja = \ parametri -> runko joten sen voi kirjoittaa siistimmin muodossa muuttuja :: ParametrinTyyppi -> TuloksenTyyppi muuttuja parametri = runko joissa parametreja voi myös olla useita. λ-merkintää \ käytetäänkin tavallisesti vain silloin kun määritellään uusi nimetön funktio. Niitä käytetään paljon funktionaalisessa ohjelmoinnissa, jossa on tavallista lähettää funktioita parametreina toisiin funktioihin ja saada tuloksena uusia funktioita laskea funktioilla. 25

10 Esimerkkinä olkoon funktioiden yhdistäminen joka määritellään matematiikassa (f g)(x) = f(g(x)) eli funktioista f ja g muodostettu f g on sellainen funktio, joka soveltaa ensin parametriin x funktiota g ja sitten tulokseen funktiota f. Haskellilla sen määritelmän voi (mutta ei ole pakko, koska Haskell tekee sen itse) kirjoittaa jossa f. g = \ x -> f (g x) 1. parametri on funktio f :: u -> v 2. parametri on funktio g :: t -> u tulos on uusi nimetön funktio tyyppiä t -> v joka yhdistää nämä 2 parametriaan. Itse asiassa merkintää...:: Tyyppi eli...on tätä Tyyppiä voi käyttää näiden määritelmien lisäksi myös Haskellin lausekkeissa ja hahmoissa. Ohjelmoija ei voi huijata näillä merkinnöillä Haskellia: 1 Haskell päättelee joka tapauksessa ohjelmoijan kirjoittamien lausekkeiden ja hahmojen tyypit itsenäisesti. 2 Sitten se vertaa saamiaan tuloksia ohjelmoijan kirjoittamiin merkintöihin. Ohjelmoija voi jättää nämä merkinnät pois koodistaan, koska Haskell päättelee tyypit itse. Hyvä periaate on jos funktio kaipaa kommenttia, niin sille kannattaa antaa myös tyyppi koska tyyppi on samalla funktion dokumentaatiota jonka kone vieläpä tarkistaa. Nyt voimme määritellä funktioita, jotka operoivat atomisten perustietotyyppien arvoilla. Käytetään esimerkkinä kertomafunktiota (8). Koska tämä funktio tuottaa pienestäkin kokonaisluvusta hyvin suuren kokonaisluvun, valitaan sen tyypiksi Int -> Integer. Nyt kohtaamme Haskellin täsmällisen tyypityksen: Int on eri tyyppi kuin Integer, joten niitä ei voi kertoa yhteen, vaikka ne molemmat ovatkin kokonaislukutyyppejä. Siten parametri n on ensin muunnettava tyypistään Int tyyppiin Integer. Täsmällisessä tyypityksessä sama arvo ei vaihda tyyppiiään, vaan siitä tuoteteaan toinen arvo, jolla on haluttu tyyppi. Tässä sen tekee Haskell-kirjastofunktio fromintegral. Myöhemmin näemme, miten Haskell on laajentanut HM-tyypinpäättelyä sallimaan tällaiset funktiot. Tämä fact on varsin konventionaalista ohjelmointia. 26

11 fact :: Int -> Integer fact n = if n < 2 then 1 else fromintegral n * fact (n-1) fact2 = fact. (2 *) fact2 on sen sijaan funktio joka on määritelty laskutoimituksella olemassa olevista funktioista eikä suoraan. Suoran määritelmän voi laskea koodiyhtälöillämme: joten suora määritelmä on fact2 δ fact. (2 *) δ fact. (\ y -> 2 * y) δ \ x -> fact ((\ y -> 2 * y) x) β \ x -> fact (2 * x) fact2 x = fact (2 * x) josta näkyy mikä funktio niin määriteltiin Paikalliset määritelmät Ohjelmoinnissa tarvitaan usein paikallisia määritelmiä, jotka ovat voimassa vain siellä, missä ohjelmoija niin määrää. Tämä voidaan ilmaista lausekkeella let { määritelmä ; määritelmä ; määritelmä... ; määritelmä } in lauseke eli nämä määritelmät ovat käytössä täsmälleen silloin kun tätä lauseketta lasketaan. Jatketaan edellistä fact-esimerkkiä. Nyt muunnetaankin Int n aluksi yhden kerran Integeriksi. Siinä määritellään kertomafunktio fact :: Integer -> Integer paikallisesti. Annetaan Haskellin päätellä sen tyyppi itse. 27

12 fact :: Int -> Integer fact = let fact n = if n < 2 then 1 else n * fact (n-1) in fact. fromintegral Nämä paikalliset määritelmät voi kirjoittaa myös muodossa lauseke where { määritelmä ; määritelmä ; määritelmä... ; määritelmä } Tässä vaihtoehtoisessa tavassa näkyvyysalue voi olla myös Hahmo eikä lauseke. Se yksinkertaistaa usein ohjelmien kirjoitusasua Suluton syntaksi Esimerkissämme ei kuitenkaan näkynyt aaltosulkeita {...} vaikka let-syntaksissa määritelmät ympäröitiin niillä ja erotettiin toisistaan puolipisteellä ;. Haskell sallii aaltosulkeiden ja puolipisteiden jättämisen pois, jos ohjelmakoodi sisennetään niin, että siitä näkyy sama informaatio. Sisennysperiaate (Marlow, 2010, luku 2.7) on seuraava: Jos aloittavan let-, where-, of- tai do-sanan jälkeen ei tulekaan avaavaa aaltosulkua {, niin avattu rakenne tulkitaan sisennetyksi. Jos näin avatun rakenteen sisällä kahden eri osan välillä pitäisi olla ; niin kumpikin niistä pitää sen sijaan sisentää alkamaan samalta sarakkeelta, ja tämän yhteisen aloitussarakkeen pitää olla jossakin rakenteen aloittaneen sanan oikealla puolella. Siis esimerkiksi jokaisen määritelmän pitää alkaa samalta sarakkeelta letin tai wheren oikealta puolelta. Jos edellisessä esimerkissämme olisi ollut useita paikallisia määritelmiä, niin jokasisen niistä olisi pitänyt alkaa samalta sarakkeelta kuin fact. Jos avatun rakenteen sisällä jokin osa koostuu monesta eri rivistä, niin sen muut rivit pitää sisentää alkamaan tämän yhteisen aloitussarakkeen sarakkeen oikealta puolelta. Siten edellisessä esimerkissämme if-lauseke on sisennetty fact -määritelmän alkukohdan oikealle puolelle. Avattu rakenne sulkeutuu kun ohjelmakoodissa kohdataan rivi, joka onkin sisennetty tämän yhteisen aloitussarakkeen vasemmalle puolelle. Edellisessä esimerkissämme se on in-rivi. 28

13 4.4 Rakenteiset tietotyypit Rakenteisten tyyppien arvot sisältävät osia, jotka ovat myöskin arvoja, ja joilla siis on omat tyyppinsä. Näiden kokonaisten arvojen sisältämiä osia pääsee tutkimaan hahmonsovituksella (pattern matching). Eräs Haskell-syntaksin suunnitteluperiaatteista on, että hahmot muistuttavat mahdollisimman paljon niitä arvoja, joihin ne sopivat. Tavoitteena on siis koodinlukutapa jos syötearvo näyttää tältä, niin sitä vastaava tulosarvo näyttää tuolta Monikot Funktion tulos koostuu usein monesta eri osasta, jotka yhdessä muodostavat vastauksen. Esimerkiksi kirjastofunktio quotrem on kokonaislukujen tarkka jakolasku jonka vastaus koostuu siis 1 osamäärästä ja 2 jakojäännöksestä eli se on kokonaislukupari. Haskell tarjoaakin valmiina tyypit kaikille pareille, kolmikoille, nelikoille,... koska muuten jokainen ohjelmoija kuitenkin määrittelisi itselleen omat sellaiset jolloin heidän koodiensa yhdistäminen olisi turhan hankalaa. Tarkemmin sanoen, Haskell tarjoaa valmiina tyyppikonstruktorit pareille, kolmikoille, nelikoille,... Tyyppi (Tyyppi_1,Tyyppi_2, Tyyppi_3,...,Tyyppi_k ) on niiden monikkojen tyyppi, jossa on k osaa, joista 1 osan arvojen tyyppi on Tyyppi_1 2 osan arvojen tyyppi on Tyyppi_2 3 osan arvojen tyyppi on Tyyppi_3 ja niin edelleen. Tämän tyypin lausekkeet ovat muotoa (lauseke_1,lauseke_2,lauseke_3,...,lauseke_k) ja hahmot muotoa (Hahmo_1,Hahmo_2,Hahmo_3,...,Hahmo_k ) josta näkyy arvojen ja lausekkeiden syntaktinen samankaltaisuusperiaate. Niiden osat vastaavat toisiaan siten, että jokainen lauseke_i :: Tyyppi_i ja Hahmo_i :: Tyyppi_i. 29

14 Haskell ei tarjoa 1-osaisia monikkotyyppejä (Tyyppi) koska sulutettu (lauseke) tai (hahmo) on sama asia kuin pelkkä suluton lauseke tai Hahmo. Haskell tarjoaa 0-osaisen monikkotyypin (). Sitä voidaan käyttää, kun funktio ei palauta kutsujalleen mitään kiinnostavaa informaatiota koska sen pitää palauttaa jotakin. Tällaisia funktioita on esimerkiksi I/O-operaatioissa, joita kutsutaan sivuvaikustensa eikä vastauksensa vuoksi esimerkiksi putstr joka tulostaa merkkijonon stdout-oletustulostustiedostoon. Haskell siis erottaa toisistaan funktiokutsut f(x,y) jossa funktiota f kutsutaan yhdellä parametrilla, joka on lausekkeiden x ja y arvoista rakennettu pari f x y jossa funktiota f kutsutaan kahdella eri parametrilla, jotka ovat lausekkeiden x ja y arvot sellaisinaan Hahmonsovitus Hahmonsovituslauseke on muotoa case lauseke of { Hahmo_1 -> tulos_1 ; Hahmo_2 -> tulos_2 ; Hahmo_3 -> tulos_3... ; Hahmo_n -> tulos_n } jonka jokainen Hahmo_i :: t on samaa tyyppiä t kuin lauseke :: t jotta niitä voidaan sovittaa sen arvoihin tulos_j :: u on keskenään samaa tyyppiä u jotta koko case-lausekkeen kaikilla mahdollisilla eri tuloksilla on sama tyyppi u. Sen intuitiivinen toiminta on: 1 Olkoon a se arvo, jonka lauseke tuotti. 2 Valitaan kirjoitusjärjestuksessa ensimmäinen Hahmo_k johon sen arvo a sopii. Koko case-lausekkeen tulos on sen tulos_k. 3 Jos yksikään Hahmo_k ei sovi arvoon a niin koko ohjelman suoritus keskeytyy ajonaikaiseen virheeseen laskennan tulosta ei ole määritelty. Koska arvo a lasketaankin laiskasti (eikä ahkerasti kuten tässä oletamme) niin tarkennamme myöhemmin, miten se tapahtuu. Esimerkiksi if ehto then tulos_t else tulos_f 30

15 on sama kuin case ehto of True -> tulos_t False -> tulos_f Hahmoina sallitaan myös muuttujat. Tavoitteena on, että tulos_k voisi käsitellä niitä osia arvosta a jotka sen Hahmo_k paljasti. Tämä tavoite saavutetaan siten, että tällainen muuttujahahmo antaa paikallisen nimen sitä vastaavalle arvon a osalle, ja tulos_k (mutta vain se) voi käyttää tätä näin annettua nimeä. Koska kyse on nimeämisestä, sama muuttuja saa esiintyä samassa Hahmossa vain kerran. Siis esimerkiksi (z,z) ei ole sallittu Hahmo vaikka sillä olisikin luonteva tulkinta: ne parit, joiden osat ovat keskenään samat. Hahmona sallitaan myös alaviiva _. Se tarkoittaa, että tulos_k ei tarvitse tätä osaa arvosta a joten sille osalle ei anneta omaa nimeä. Hahmona sallitaan myös joka on kuin sisältämänsä Hahmo ja sen lisäksi nimeää koko siihen sopineen arvon tällä muuttujalla. Esimerkiksi sopii sellaisiin pareihin, joiden ensimmäinen osa on 5, ja se antaa parin toiselle osalle nimeksi y ja koko parille nimeksi x. Esimerkiksi case x quotrem y of (q,r) -> tulos antaa tuloslausekkeessa nimen q osamäärälle (quotient) ja nimen r jakojäännökselle (remainder) kun kokonaisluku x jaetaan kokonaisluvulla y. Tällainen nimeäminen voikaan kirjoittaa helpommin let (q,r) = x quotrem y in tulos sallimalla myös tällaiset määritelmät joiden vasen puoli (ennen yhtäsuuruusmerkkiä = ) onkin kokonainen Hahmo eikä pelkkä nimi. Hahmoon voi liittää vartijan (guard). Sen syntaksi on Hahmo vartija jossa vartija :: Bool on lauseke. Arvo a sopii tällaiseen vartioituun Hahmoon vain jos myös sen vartija on True. Tällä vartijalla voi siten ilmaista semanttisen lisäehdon, jonka pitää myös olla voimassa syntaktisen Hahmonsovituksen lisäksi. Esimerksi ne parit, joiden osat ovat keskenään samat voi ilmaista vartioidulla Hahmolla (z,z ) z==z. 31

16 Sen vuoksi vartijassa saa käyttää (myös) niitä muuttujia jotka tämä Hahmo esitteli, kuten z ja z tässä esimerkissä. Sama Hahmo voi toistua monta kertaa peräkkäin koska siinä Hahmo vartija_1 = tulos_1 Hahmo vartija_2 = tulos_2 Hahmo vartija_3 = tulos_3... Hahmo vartija_m = tulos_m 1 ensin arvo a sovitetaan tähän yhteiseen Hahmoon, ja jos se onnistuu niin 2 sitten valitaan ensimmäinen vartija_i joka on True ja sitä vastaava tulos_i. Silloin tätä yhteistä Hahmoa ei tarvitse toistaa, vaan riittää. Hahmo vartija_1 = tulos_1 vartija_2 = tulos_2 vartija_3 = tulos_3... vartija_m = tulos_m Saman Hahmon eri vartijat voivat tarvita yhteisiä paikallisia määrittelyjä. Ne voidaan kirjoittaa Hahmo vartija_1 = tulos_1 vartija_2 = tulos_2 vartija_3 = tulos_3... vartija_m = tulos_m where määrittely määrittely määrittely... määrittely paljon helpommin kuin letillä. Matematiikassa on yleistä määritellä funktio tapauksittain. Esimerkiksi Fibonaccin luvut voidaan määritellä 0 kun n = 0 fib(n) = 1 kun n = 1 fib(n 1) + fib(n 2) kun n > 1 joka voidaan kirjoittaa jopa muodossa fib(0) = 0 fib(1) = 1 fib(n) = fib(n 1) + fib(n 2) jossa ideana on lukea tapauksia niiden kirjoitusjärjestyksessä ja valita niistä ensimmäinen joka sopii. 32

17 Myös Haskellissa on tavallista määritellä funktio niin, että se valitsee tuloksensa suoraan parametrinsa perusteella: funktio parametri = case parametri of Hahmo_1 -> tulos_1 Hahmo_2 -> tulos_2 Hahmo_3 -> tulos_3... Hahmo_n -> tulos_n Niinpä tämä voidaankin kirjoittaa vastaavassa muodossa tapauksittain funktio Hahmo_1 = tulos_1 funktio Hahmo_2 = tulos_2 funktio Hahmo_3 = tulos_3... funktio Hahmo_n = tulos_n jonka jokaisella tapauksella on luonteva luenta: Jos funktion parametri sopii tähän Hahmoon niin tässä on vastaava tulos. fib :: Integer -> Integer fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) foo = (\ (q,r) -> q * r). ( quotrem 2) bar = uncurry (*). ( quotrem 2) Koska nimetyn funktion parametri saa olla Hahmo niin sallitaan sama myös nimettömissä funktioissa. Tämä Haskell-funktion määrittely tapauksittain on luonteva työväline käsiteltäessä Haskell-kielen rakenteisia tietotyyppejä, jotka myöskin määritellään tapauksittain Listat Haskell tarjoaa valmiina tyyppikonstruktorin listoille, samasta syystä kuin se tarjoaa tyyppikonstruktorit eri kokoisille monikoille. Funktionaalisessa ohjelmoinnissa käytetään paljon listoja. Laiskuuden ja listojen yhdistelmä on erityisen monikäyttöinen. 33

18 Kaikkien Haskell-listassa olevien alkioiden pitää olla keskenään samaa tyyppiä, jotta listan sisältöä käsiteltäessä tiedetään minkä tyyppisiä arvoja siellä kohdataan. Tyyppi listat, joiden alkiot ovat tyyppiä t kirjoitetaan [t]. Tyyppiä [t] olevan listan perussyntaksi on tyhjä lista jonka lauseke ja Hahmo on [] epätyhjä lista jonka lauseke tai Hahmo on eka:muut jossa eka :: t on listan ensimmäisen alkion ja muut :: [t] loppulistan lauseke tai Hahmo. Listat ovat ensimmäinen itseensä viittaavasti eli rekursiivisesti määritelty tietotyyppimme: Epätyhjä lista koostuu ekasta alkiosta ja loppulistasta jossa ovat muut sen alkiot tällä samalla tavalla. Listoilla [] on parametriton eli vakio- (:) on 2-parametrinen (arvo)konstruktori: Nimi, joka voi esiintyä lausekkeessa jolloin se merkitsee funktiota, joka luo parametreistaan uuden tämän tyyppisen arvon esimerkiksi (:) :: t -> [t] -> [t] hahmossa jolloin se sopii täsmälleen niihin arvoihin, jotka on luotu juuri tällä funktiolla esimerkiksi a :cs sopii täsmälleen niihin listoihin tyyppiä [Char] jotka alkavat merkillä a. Haskell-syntaksissa on sovittu, että operaattoreista konstruktoreita ovat ne, joiden nimi alkaa kaksoispisteellä : kuten tässä. Konstruktorioperaattori (:) assosoi oikealle joten eka:(toka:(kolmas:loput)) voidaan kirjoittaa ilman sulkuja eka:toka:kolmas:loput. Jos listan pituus tiedetään ennalta, niin sen alkiot voidaan kirjoittaa hakasulkeiden [...] sisään pilkuin, eroteltuina. Esimerkiksi 3-alkioinen lauseke tai Hahmo kuten eka:toka:kolmas:[] voidaan kirjoittaa [eka,toka,kolmas]. Jos kyseessä on merkkivakioiden lista jonka pituus tiedetään ennalta eli merkkijonovakio, niin merkit voidaan kirjoittaa tuttuun tapaan peräkkäin kaksinkertaisten lainausmerkkien "..." väliin ilman erottelevia pilkkuja,. Esimerkiksi [ a, b, c ] voidaan kirjoittaa "abc". TRA-kurssien käsittein kyseessä on yhteen suuntaan linkitetty lista, jota esittää osoitin sen ensimmäiseen alkioon (mutta ei viimeiseen) mutta Haskell-ohjelmoija ei näe näitä osoittimia, jotka ovat kielen toteutustason väline. 34

19 Listojen käsittelystä Koska Haskell-listat on määritelty rekursiivisesti, niin niitä on luontevaa myös käsitellä rekursiivisesti määritelmänsä suhteen. Toisin sanoen, jos Haskell-funktio saa parametrinaan listan, niin se on luontevaa määritellä tapauksittain: Mitä funktion pitäisi palauttaa... tyhjälle listalle []? epätyhjälle listalle eka:muut jossa muut voidaan käsitellä rekursiivisesti tällä samalla funktiolla? Myös Haskell-syntaksi tukee tällaista ohjelmointia: funktio [] = z funktio (eka:muut) = f eka (funktio muut) jossa lausekkeet z ja f riippuvat siitä, mitä funktion halutaan laskevan. Haskell lataa käynnistyessään automaattisesti vakiokirjaston nimeltä Prelude joka sisältää mm. funktion foldr jonka 1. parametri on tämä funktio f :: t -> u -> u 2. parametri on tämä vakio z :: u tulos on uusi funktio tyyppiä [t] -> u joka toteuttaa tämän listarekursion. Haskell-koodina se on: foldr _ z [] = z foldr f z (x:xs) = f x (foldr f z xs) Usein käytetty nimentätapa: one x, many other xs. Funktionaalisessa ohjelmoinnissa kehitetään ja hyödynnetään usein tällaisia funktioita, jotka ilmaisevat abstraktisti jonkin yleisperiaatteen tässä tätä on rekursio listan rakenteen suhteen soveltuvat moniin eri käyttötarkoituksiin, koska niitten toimintaa voi varioida funktiotyyppisillä parametreilla tässä f. Esimerkiksi funktiot totuusarvolistan alkioiden konjunktio ja... disjunktio voidaan nyt määritellä and = foldr (&&) True or = foldr ( ) False Voimme laskea vaikkapa 35

20 and [x_1,x_2,x_3,...,x_n] = foldr (&&) True [x_1,x_2,x_3,...,x_n] = (&&) x_1 (foldr (&&) True [x_1,x_2,x_3,...,x_n]) = x_1 && (foldr (&&) True [x_2,x_3,...,x_n])... = x_1 && x_2 && x_3 &&... && x_n && True = x_1 && x_2 && x_3 &&... && x_n joten näin todellakin on. Osaako näin määritelty and pysähtyä heti jos se kohtaa syötelistassaan Falsen, vai jatkaako se silloinkin rekursiolla koko listan loppuun? Operaattori (&&) on määritelty Lasketaanpa: True && x = x False && _ = False and [True,False,True,...] = foldr (&&) True [True,False,True,...] = (&&) True (foldr (&&) True [False,True,...]) = foldr (&&) True [False,True,...] = (&&) False (foldr (&&) True [True,...]) = False eli kyllä laiska suoritus osaa! Tämä osaaminen johtuu siitä, että foldr-rekursiohaara vie parametrin f siihen kohtaan, josta laiska suoritus etsii seuraavan redeksinsä eli f suoritetaankin seuraavaksi ennen rekursiivista foldr-rekursiokutsua. Preludessa on myös listan tuttu läpikäynti järjestyksessä silmukalla 1 while lista ei ole vielä lopussa 2 z = f z listan nykyinen alkio; 3 siirry listan sitä seuraavaan alkioon; 4 return z funktiona foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs eli fold left. foldl ei kuitenkaan osaakaan pysähtyä heti, koska siinä seuraavan redeksinä onkin joka kierroksella foldl itse: foldl (&&) True [True,False,True,...] = foldl (&&) (True && True) [False,True,...] = foldl (&&) ((True && True) && False) [True,...] = foldl (&&) (((True && True) && False) && True) [...] =... 36

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla 2.5. YDIN-HASKELL 19 tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla kirjaimilla. Jos Γ ja ovat tyyppilausekkeita, niin Γ on tyyppilauseke. Nuoli kirjoitetaan koneella

Lisätiedot

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Tällä luennolla Algebralliset tietotyypit Hahmonsovitus (pattern matching) Primitiivirekursio Esimerkkinä binäärinen hakupuu Muistattehan...

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 6 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Tyyppejä ja vähän muutakin TIEA341 Funktio ohjelmointi 1 Syksy 2005 Viime luennolla... Haskellin alkeita pääasiassa Hello World!... ja muita tutunoloisia ohjelmia Haskellilla Haskellin voima on kuitenkin

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 2 vastaukset Harjoituksen aiheena on BNF-merkinnän käyttö ja yhteys rekursiivisesti etenevään jäsentäjään. Tehtävä 1. Mitkä ilmaukset seuraava

Lisätiedot

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset 815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 3 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten muuttujiin liittyvät kysymykset. Tehtävä 1. Määritä muuttujien max_num, lista,

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 5 Ympärysmitta. Puut. Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 CASE: YMPÄRYSMITTA Lasketaan kuvioiden ympärysmittoja

Lisätiedot

Luku 3. Listankäsittelyä. 3.1 Listat

Luku 3. Listankäsittelyä. 3.1 Listat Luku 3 Listankäsittelyä Funktio-ohjelmoinnin tärkein yksittäinen tietorakenne on lista. Listankäsittely on paitsi käytännöllisesti oleellinen aihe, se myös valaisee funktio-ohjelmoinnin ideaa. 3.1 Listat

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2009 1 / 28 Puhelinluettelo, koodi def lue_puhelinnumerot(): print "Anna lisattavat nimet ja numerot." print

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 4 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 17. tammikuuta 2008 Modulin viimeistelyä module Shape ( Shape ( Rectangle, E l l i p

Lisätiedot

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014 18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 4 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten lauseisiin, lausekkeisiin ja aliohjelmiin liittyvät kysymykset. Tehtävä 1. Mitä

Lisätiedot

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5) Alkuarvot ja tyyppimuunnokset (1/5) Aiemmin olemme jo antaneet muuttujille alkuarvoja, esimerkiksi: int luku = 123; Alkuarvon on oltava muuttujan tietotyypin mukainen, esimerkiksi int-muuttujilla kokonaisluku,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 19.1.2011 T-106.1208 Ohjelmoinnin perusteet Y 19.1.2011 1 / 39 Haluatko antaa palautetta luennoista? Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti Vast

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.4.2009 T-106.1208 Ohjelmoinnin perusteet Y 1.4.2009 1 / 56 Tentti Ensimmäinen tenttimahdollisuus on pe 8.5. klo 13:00 17:00 päärakennuksessa. Tämän jälkeen

Lisätiedot

Johdatus Ohjelmointiin

Johdatus Ohjelmointiin Johdatus Ohjelmointiin Syksy 2006 Viikko 2 13.9. - 14.9. Tällä viikolla käsiteltävät asiat Peruskäsitteitä Kiintoarvot Tiedon tulostus Yksinkertaiset laskutoimitukset Muuttujat Tiedon syöttäminen Hyvin

Lisätiedot

Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia, niin A on rekursiivinen.

Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia, niin A on rekursiivinen. Lause: Tyhjyysongelma ei ole osittain ratkeava; ts. kieli ei ole rekursiivisesti lueteltava. L e = { w { 0, 1 } L(M w ) = } Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia,

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 22. huhtikuuta 2016 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille! Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin. 2. Ohjausrakenteet Ohjausrakenteiden avulla ohjataan ohjelman suoritusta. peräkkäisyys valinta toisto Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 30.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 30.9.2015 1 / 27 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

Ydin-Haskell Tiivismoniste

Ydin-Haskell Tiivismoniste Ydin-Haskell Tiivismoniste Antti-Juhani Kaijanaho 8. joulukuuta 2005 1 Abstrakti syntaksi Päätesymbolit: Muuttujat a, b, c,..., x, y, z,... Tyyppimuuttujat α, β, γ,... Koostimet (data- ja tyyppi-) C, D,...,

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CS-A1111 14.9.2016 CS-A1111 Ohjelmoinnin peruskurssi Y1 14.9.2016 1 / 19 Oppimistavoitteet: tämän luennon jälkeen osaat kirjoittaa Python-ohjelman, joka pyytää käyttäjältä lukuja,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 10.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 10.2.2010 1 / 43 Kertausta: listat Tyhjä uusi lista luodaan kirjoittamalla esimerkiksi lampotilat = [] (jolloin

Lisätiedot

Ohjelmointiharjoituksia Arduino-ympäristössä

Ohjelmointiharjoituksia Arduino-ympäristössä Ohjelmointiharjoituksia Arduino-ympäristössä Yleistä Arduino-sovelluksen rakenne Syntaksi ja käytännöt Esimerkki ohjelman rakenteesta Muuttujat ja tietotyypit Tietotyypit Esimerkkejä tietotyypeistä Ehtolauseet

Lisätiedot

Tämän vuoksi kannattaa ottaa käytännöksi aina kirjoittaa uuden funktion tyyppi näkyviin, ennen kuin alkaa sen määritemää kirjoittamaan.

Tämän vuoksi kannattaa ottaa käytännöksi aina kirjoittaa uuden funktion tyyppi näkyviin, ennen kuin alkaa sen määritemää kirjoittamaan. 3.1. LISTAT 35 destaan pisteittäisesti: init :: [α] [α] init (x : []) = [] init (x : xs) = x : init xs Varuskirjastoon kuuluu myös funktiot take ja drop, jotka ottavat tai tiputtavat pois, funktiosta riippuen,

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, Vakio Tiedon merkkipohjainen tulostaminen Ohjelmointi (ict1tx006) Tunnus (5.3) Javan tunnus Java-kirjain Java-numero

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.3.2010 1 / 56 Tiedostoista: tietojen tallentaminen ohjelman suorituskertojen välillä Monissa sovelluksissa ohjelman

Lisätiedot

Demo 7 ( ) Antti-Juhani Kaijanaho. 9. joulukuuta 2005

Demo 7 ( ) Antti-Juhani Kaijanaho. 9. joulukuuta 2005 Demo 7 (14.12.2005) Antti-Juhani Kaijanaho 9. joulukuuta 2005 Liitteenä muutama esimerkki Ydin-Haskell-laskuista. Seuraavassa on enemmän kuin 12 nimellistä tehtävää; ylimääräiset ovat bonustehtäviä, joilla

Lisätiedot

TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 26. kesäkuuta 2013

TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 26. kesäkuuta 2013 ja ja TIEA241 Automaatit ja kieliopit, kesä 2012 Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 26. kesäkuuta 2013 Sisällys ja ja on yksi vanhimmista tavoista yrittää mallittaa mekaanista laskentaa. Kurt

Lisätiedot

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti Luku 6 Dynaaminen ohjelmointi Dynaamisessa ohjelmoinnissa on ideana jakaa ongelman ratkaisu pienempiin osaongelmiin, jotka voidaan ratkaista toisistaan riippumattomasti. Jokaisen osaongelman ratkaisu tallennetaan

Lisätiedot

Alityypitys. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos

Alityypitys. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos Alityypitys TIES542 Ohjelmointikielten periaatteet, kevät 2007 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 5. maaliskuuta 2007 Muistatko tietueet? {I 1 = E 1,..., I n = E n } : {I

Lisätiedot

Tietotyypit ja operaattorit

Tietotyypit ja operaattorit Tietotyypit ja operaattorit Luennossa tarkastellaan yksinkertaisten tietotyyppien int, double ja char muunnoksia tyypistä toiseen sekä esitellään uusia operaatioita. Numeeriset tietotyypit ja muunnos Merkkitieto

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 9.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 9.9.2015 1 / 26 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 17.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 17.2.2010 1 / 41 Sanakirja Monissa sovelluksissa on tallennettava rakenteeseen avain arvo-pareja. Myöhemmin rakenteesta

Lisätiedot

5/20: Algoritmirakenteita III

5/20: Algoritmirakenteita III Ohjelmointi 1 / syksy 2007 5/20: Algoritmirakenteita III Paavo Nieminen nieminen@jyu.fi Tietotekniikan laitos Informaatioteknologian tiedekunta Jyväskylän yliopisto Ohjelmointi 1 / syksy 2007 p.1/17 Tämän

Lisätiedot

815338A Ohjelmointikielten periaatteet

815338A Ohjelmointikielten periaatteet 815338A Ohjelmointikielten periaatteet 2015-2016 VI Funktionaalinen ohjelmointi Sisältö 1. Johdanto ja peruskäsitteitä 2. LISP- ja Scheme-kielet 3. Haskell 4. IO funktionaalisissa kielissä 5. Muita funktionaalisia

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 4 Jatkuvuus Jatkuvan funktion määritelmä Tarkastellaan funktiota f x) jossakin tietyssä pisteessä x 0. Tämä funktio on tässä pisteessä joko jatkuva tai epäjatkuva. Jatkuvuuden

Lisätiedot

Täydentäviä muistiinpanoja laskennan rajoista

Täydentäviä muistiinpanoja laskennan rajoista Täydentäviä muistiinpanoja laskennan rajoista Antti-Juhani Kaijanaho 10. joulukuuta 2015 1 Diagonaalikieli Diagonaalikieli on D = { k {0, 1} k L(M k ) }. Lause 1. Päätösongelma Onko k {0, 1} sellaisen

Lisätiedot

Pysähtymisongelman ratkeavuus [Sipser luku 4.2]

Pysähtymisongelman ratkeavuus [Sipser luku 4.2] Pysähtymisongelman ratkeavuus [Sipser luku 4.2] Osoitamme nyt vihdoin, että jotkin Turing-tunnistettavat kielet ovat ratkeamattomia ja jotkin kielet eivät ole edes Turing-tunnistettavia. Lisäksi toteamme,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 16.2.2010 1 / 41 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Osoittimet Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Muistilohkon koko riippuu muuttujan tyypistä, eli kuinka suuria arvoja muuttujan

Lisätiedot

PERL. TIE Principles of Programming Languages. Ryhmä 4: Joonas Lång & Jasmin Laitamäki

PERL. TIE Principles of Programming Languages. Ryhmä 4: Joonas Lång & Jasmin Laitamäki PERL TIE-20306 Principles of Programming Languages Ryhmä 4: Joonas Lång & Jasmin Laitamäki 1. Johdanto Perl on ohjelmointikielten perhe, johon kuuluu Perl 5 ja Perl 6. Kielet ovat kuitenkin erilliset ohjelmointikielet

Lisätiedot

Yhtälönratkaisusta. Johanna Rämö, Helsingin yliopisto. 22. syyskuuta 2014

Yhtälönratkaisusta. Johanna Rämö, Helsingin yliopisto. 22. syyskuuta 2014 Yhtälönratkaisusta Johanna Rämö, Helsingin yliopisto 22. syyskuuta 2014 Yhtälönratkaisu on koulusta tuttua, mutta usein sitä tehdään mekaanisesti sen kummempia ajattelematta. Jotta pystytään ratkaisemaan

Lisätiedot

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset Harjoituksen aiheena ovat aliohjelmat ja abstraktit tietotyypit sekä olio-ohjelmointi. Tehtävät tehdään C-, C++- ja Java-kielillä.

Lisätiedot

12. Javan toistorakenteet 12.1

12. Javan toistorakenteet 12.1 12. Javan toistorakenteet 12.1 Sisällys Yleistä toistorakenteista. Laskurimuuttujat. While-, do-while- ja for-lauseet. Laskuri- ja lippumuuttujat. Tyypillisiä ohjelmointivirheitä. Silmukan rajat asetettu

Lisätiedot

1 Määrittelyjä ja aputuloksia

1 Määrittelyjä ja aputuloksia 1 Määrittelyjä ja aputuloksia 1.1 Supremum ja infimum Aluksi kerrataan pienimmän ylärajan (supremum) ja suurimman alarajan (infimum) perusominaisuuksia ja esitetään muutamia myöhemmissä todistuksissa tarvittavia

Lisätiedot

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public) Tietorakenteet JAVA-OHJELMOINTI Osa 5: Tietorakenteita Eero Hyvönen Tietojenkäsittelytieteen laitos Helsingin yliopisto Olioita ja tietoja voidaan organisoida määrämuotoisiksi tietorakenteiksi Hyödyllisiä

Lisätiedot

4. Lausekielinen ohjelmointi 4.1

4. Lausekielinen ohjelmointi 4.1 4. Lausekielinen ohjelmointi 4.1 Sisällys Konekieli, symbolinen konekieli ja lausekieli. Lausekielestä konekieleksi: - Lähdekoodi, tekstitiedosto ja tekstieditorit. - Kääntäminen ja tulkinta. - Kääntäminen,

Lisätiedot

Algoritmit 1. Luento 2 Ke Timo Männikkö

Algoritmit 1. Luento 2 Ke Timo Männikkö Algoritmit 1 Luento 2 Ke 11.1.2017 Timo Männikkö Luento 2 Algoritmin esitys Algoritmien analysointi Suoritusaika Asymptoottinen kertaluokka Peruskertaluokkia NP-täydelliset ongelmat Algoritmit 1 Kevät

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.2.2010 1 / 46 Merkkijonot Merkkijonojen avulla ohjelmassa voi esittää tekstitietoa, esim. nimiä, osoitteita ja

Lisätiedot

lausekkeiden tapauksessa. Jotkin ohjelmointikielet on määritelty sellaisiksi,

lausekkeiden tapauksessa. Jotkin ohjelmointikielet on määritelty sellaisiksi, 3.5. TYYPIT 59 indeksit voidaan siirtää kielitasolta oliotasolle siirryttäessä alkamaan nollasta. Vain mikäli indeksin alin arvo oliotasolla ei ole tiedossa ennen suorituksen alkua, on tarpeen lisätä taulukko-olioon

Lisätiedot

Uusi näkökulma. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Uusi näkökulma. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Uusi näkökulma TIEA341 Funktio ohjelmointi 1 Syksy 2005 Aloitetaan alusta... Otetaan uusi näkökulma Haskelliin ohjelmointi laskentana kertausta toisaalta, uusia käsitteitä toisaalta helpottanee sitten

Lisätiedot

Sisällys. 12. Javan toistorakenteet. Yleistä. Laskurimuuttujat

Sisällys. 12. Javan toistorakenteet. Yleistä. Laskurimuuttujat Sisällys 12. Javan toistorakenteet Ylstä toistorakentsta. Laskurimuuttujat. While-, do-while- ja for-lauseet. Laskuri- ja lippumuuttujat. Tyypillisiä ohjelmointivirhtä. Silmukan rajat asetettu kierroksen

Lisätiedot

5. HelloWorld-ohjelma 5.1

5. HelloWorld-ohjelma 5.1 5. HelloWorld-ohjelma 5.1 Sisällys Lähdekoodi. Lähdekoodin (osittainen) analyysi. Lähdekoodi tekstitiedostoon. Lähdekoodin kääntäminen tavukoodiksi. Tavukoodin suorittaminen. Virheiden korjaaminen 5.2

Lisätiedot

Mathematica Sekalaista asiaa

Mathematica Sekalaista asiaa Mathematica Sekalaista asiaa Asetusoperaattorit Mathematicassa voi käyttää omia muuttujasymboleja melko rajattomasti ja niiden nimeämisessä voi käyttää miltei mitä tahansa merkkejä. Käytännössä nimeämisessä

Lisätiedot

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 2. Taulukot. Yleistä. Yleistä Sisältö 2. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.1 2.2 Yleistä

Lisätiedot

Taas laskin. TIES341 Funktio ohjelmointi 2 Kevät 2006

Taas laskin. TIES341 Funktio ohjelmointi 2 Kevät 2006 Taas laskin TIES341 Funktio ohjelmointi 2 Kevät 2006 Rakennepuutyyppi data Term = C Rational T F V String Term :+: Term Term : : Term Term :*: Term Term :/: Term Term :==: Term Term :/=: Term Term :

Lisätiedot

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys Loogisia operaatioita - esimerkkejä Tänään on lämmin päivä ja perjantai Eilen satoi ja oli keskiviikko tai tänään on tiistai. On perjantai ja kello on yli 13 Ei ole tiistai tai ei sada. Ei pidä paikkaansa,

Lisätiedot

Ohjelmointi 1 C#, kevät 2014, 2. uusintatentti NIMI:

Ohjelmointi 1 C#, kevät 2014, 2. uusintatentti NIMI: ITKP102 Ohjelmointi 1 C# 13.6.2014 1 / 5 Ohjelmointi 1 C#, kevät 2014, 2. uusintatentti Tentaattori Antti-Jussi Lakanen Valitse neljä tehtävää ja vastaa niihin. Keväällä 2014 kurssin tehneille lasketaan

Lisätiedot

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma. 2. Taulukot 2.1 Sisältö Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.2 Yleistä

Lisätiedot

Kuvauksista ja relaatioista. Jonna Makkonen Ilari Vallivaara

Kuvauksista ja relaatioista. Jonna Makkonen Ilari Vallivaara Kuvauksista ja relaatioista Jonna Makkonen Ilari Vallivaara 20. lokakuuta 2004 Sisältö 1 Esipuhe 2 2 Kuvauksista 3 3 Relaatioista 8 Lähdeluettelo 12 1 1 Esipuhe Joukot ja relaatiot ovat periaatteessa äärimmäisen

Lisätiedot

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista Sisällys 1. Omat operaatiot Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

13. Loogiset operaatiot 13.1

13. Loogiset operaatiot 13.1 13. Loogiset operaatiot 13.1 Sisällys Loogiset operaatiot AND, OR, XOR ja NOT. Operaatioiden ehdollisuus. Bittioperaatiot. Loogiset operaatiot ohjausrakenteissa. Loogiset operaatiot ja laskentajärjestys.

Lisätiedot

Reaalilukuvälit, leikkaus ja unioni (1/2)

Reaalilukuvälit, leikkaus ja unioni (1/2) Luvut Luonnolliset luvut N = {0, 1, 2, 3,... } Kokonaisluvut Z = {..., 2, 1, 0, 1, 2,... } Rationaaliluvut (jaksolliset desimaaliluvut) Q = {m/n m, n Z, n 0} Irrationaaliluvut eli jaksottomat desimaaliluvut

Lisätiedot

M = (Q, Σ, Γ, δ, q 0, q acc, q rej )

M = (Q, Σ, Γ, δ, q 0, q acc, q rej ) 6. LASKETTAVUUSTEORIAA Churchin Turingin teesi: Mielivaltainen (riittävän vahva) laskulaite Turingin kone. Laskettavuusteoria: Tarkastellaan mitä Turingin koneilla voi ja erityisesti mitä ei voi laskea.

Lisätiedot

TIE Principles of Programming Languages CEYLON

TIE Principles of Programming Languages CEYLON TIE-20306 Principles of Programming Languages CEYLON SISÄLLYSLUETTELO 1. YLEISTIETOA KIELESTÄ JA SEN KEHITTÄMISESTÄ... 1 2. CEYLONIN OMINAISUUKSIA... 2 2.1 Modulaarisuus... 2 2.2 Tyypit... 2 2.3 Muita

Lisätiedot

Ohjelmointi 1 C#, kevät 2013,

Ohjelmointi 1 C#, kevät 2013, Ohjelmointi 1 C#, kevät 2013, 19.4.2013 (English versions of the questions can be requested from the supervisor. Englanninkieliset kysymykset saa pyytämällä tentin valvojalta.) Tentti (yliopisto opiskelijat)

Lisätiedot

LOAD R1, =2 Sijoitetaan rekisteriin R1 arvo 2. LOAD R1, 100

LOAD R1, =2 Sijoitetaan rekisteriin R1 arvo 2. LOAD R1, 100 Tiedonsiirtokäskyt LOAD LOAD-käsky toimii jälkimmäisestä operandista ensimmäiseen. Ensimmäisen operandin pitää olla rekisteri, toinen voi olla rekisteri, vakio tai muistiosoite (myös muuttujat ovat muistiosoitteita).

Lisätiedot

1. Omat operaatiot 1.1

1. Omat operaatiot 1.1 1. Omat operaatiot 1.1 Sisällys Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

Harjoitus 1 -- Ratkaisut

Harjoitus 1 -- Ratkaisut Kun teet harjoitustyöselostuksia Mathematicalla, voit luoda selkkariin otsikon (ja mahdollisia alaotsikoita...) määräämällä soluille erilaisia tyylejä. Uuden solun tyyli määrätään painamalla ALT ja jokin

Lisätiedot

Ohjelmointi 1 C#, kevät 2013, 2. tentti

Ohjelmointi 1 C#, kevät 2013, 2. tentti ITKP102 Ohjelmointi 1 C# 15.5.2013 1 / 6 Ohjelmointi 1 C#, kevät 2013, 2. tentti Tentaattori Antti-Jussi Lakanen Tässä tentissä saa olla mukana omia muistiinpanoja yhden arkin verran. Tentin valvojalla

Lisätiedot

Groovy. Samuli Haverinen, Aki Hänninen. 19. marraskuuta 2015

Groovy. Samuli Haverinen, Aki Hänninen. 19. marraskuuta 2015 Groovy Samuli Haverinen, Aki Hänninen 19. marraskuuta 2015 Groovy on oliokieli Java-alustalle (käännetään/tulkataan Java-tavukoodiksi), jonka syntaksi on hyvin Java-ystävällinen ja jota voidaan käyttää

Lisätiedot

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit Liite E - Esimerkkiprojekti E Esimerkkiprojekti Olet lukenut koko kirjan. Olet sulattanut kaiken tekstin, Nyt on aika soveltaa oppimiasi uusia asioita pienen, mutta täydellisesti muotoiltuun, projektiin.

Lisätiedot

Harjoitustyö: virtuaalikone

Harjoitustyö: virtuaalikone Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman

Lisätiedot

Tietorakenteet ja algoritmit syksy Laskuharjoitus 1

Tietorakenteet ja algoritmit syksy Laskuharjoitus 1 Tietorakenteet ja algoritmit syksy 2012 Laskuharjoitus 1 1. Tietojenkäsittelijä voi ajatella logaritmia usein seuraavasti: a-kantainen logaritmi log a n kertoo, kuinka monta kertaa luku n pitää jakaa a:lla,

Lisätiedot

Approbatur 3, demo 1, ratkaisut A sanoo: Vähintään yksi meistä on retku. Tehtävänä on päätellä, mitä tyyppiä A ja B ovat.

Approbatur 3, demo 1, ratkaisut A sanoo: Vähintään yksi meistä on retku. Tehtävänä on päätellä, mitä tyyppiä A ja B ovat. Approbatur 3, demo 1, ratkaisut 1.1. A sanoo: Vähintään yksi meistä on retku. Tehtävänä on päätellä, mitä tyyppiä A ja B ovat. Käydään kaikki vaihtoehdot läpi. Jos A on rehti, niin B on retku, koska muuten

Lisätiedot

ja λ 2 = 2x 1r 0 x 2 + 2x 1r 0 x 2

ja λ 2 = 2x 1r 0 x 2 + 2x 1r 0 x 2 Johdatus diskreettiin matematiikkaan Harjoitus 4, 7.10.2015 1. Olkoot c 0, c 1 R siten, että polynomilla r 2 c 1 r c 0 on kaksinkertainen juuri. Määritä rekursioyhtälön x n+2 = c 1 x n+1 + c 0 x n, n N,

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet String-merkkijonoluokka 1 Ohjelmointikielten merkkijonot Merkkijonot ja niiden käsittely on välttämätöntä ohjelmoinnissa Valitettavasti ohjelmointikielten tekijät eivät tätä ole ottaneet

Lisätiedot

Hohde Consulting 2004

Hohde Consulting 2004 Luento 5: XQuery AS-0.110 XML-kuvauskielten perusteet Janne Kalliola XQuery XQuery uudet funktiot sekvenssit muuttujat Iterointi järjestys suodatus järjestäminen Ehtorakenteet Muita toimintoja www.hohde.com

Lisätiedot

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU Ohjelmointi 2 Jussi Pohjolainen TAMK» Tieto- ja viestintäteknologia Tietotyypeistä C++ - kielessä useita tietotyyppejä Kirjaimet: char, wchar_t Kokonaisluvut: short, int, long Liukuluvut: float, double

Lisätiedot

Imperatiivisen ohjelmoinnin peruskäsitteet. Meidän käyttämän pseudokielen lauseiden syntaksi

Imperatiivisen ohjelmoinnin peruskäsitteet. Meidän käyttämän pseudokielen lauseiden syntaksi Imperatiivisen ohjelmoinnin peruskäsitteet muuttuja muuttujissa oleva data voi olla yksinkertaista eli primitiivistä (esim. luvut ja merkit) tai rakenteista jolloin puhutaan tietorakenteista. puhuttaessa

Lisätiedot

Injektio (1/3) Funktio f on injektio, joss. f (x 1 ) = f (x 2 ) x 1 = x 2 x 1, x 2 D(f )

Injektio (1/3) Funktio f on injektio, joss. f (x 1 ) = f (x 2 ) x 1 = x 2 x 1, x 2 D(f ) Injektio (1/3) Määritelmä Funktio f on injektio, joss f (x 1 ) = f (x 2 ) x 1 = x 2 x 1, x 2 D(f ) Seurauksia: Jatkuva injektio on siis aina joko aidosti kasvava tai aidosti vähenevä Injektiolla on enintään

Lisätiedot

7/20: Paketti kasassa ensimmäistä kertaa

7/20: Paketti kasassa ensimmäistä kertaa Ohjelmointi 1 / syksy 2007 7/20: Paketti kasassa ensimmäistä kertaa Paavo Nieminen nieminen@jyu.fi Tietotekniikan laitos Informaatioteknologian tiedekunta Jyväskylän yliopisto Ohjelmointi 1 / syksy 2007

Lisätiedot

11/20: Konepelti auki

11/20: Konepelti auki Ohjelmointi 1 / syksy 2007 11/20: Konepelti auki Paavo Nieminen nieminen@jyu.fi Tietotekniikan laitos Informaatioteknologian tiedekunta Jyväskylän yliopisto Ohjelmointi 1 / syksy 2007 p.1/11 Tämän luennon

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 16.3.2009 1 / 40 Kertausta: tiedostosta lukeminen Aluksi käsiteltävä tiedosto pitää avata: tiedostomuuttuja = open("teksti.txt","r")

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 26.10.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 26.10.2015 1 / 28 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta

Lisätiedot

Algoritmit 1. Luento 4 Ke Timo Männikkö

Algoritmit 1. Luento 4 Ke Timo Männikkö Algoritmit 1 Luento 4 Ke 18.1.2017 Timo Männikkö Luento 4 Tietorakenteet Pino Pinon toteutus Jono Jonon toteutus Lista Listaoperaatiot Algoritmit 1 Kevät 2017 Luento 4 Ke 18.1.2017 2/29 Pino Pino, stack,

Lisätiedot

11. Javan toistorakenteet 11.1

11. Javan toistorakenteet 11.1 11. Javan toistorakenteet 11.1 Sisällys Laskuri- ja lippumuuttujat. Sisäkkäiset silmukat. Tyypillisiä ohjelmointivirheitä: Silmukan rajat asetettu kierroksen verran väärin. Ikuinen silmukka. Silmukoinnin

Lisätiedot

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 5. marraskuuta 2015

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 5. marraskuuta 2015 TIEA24 Automaatit ja kieliopit, syksy 205 Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 5. marraskuuta 205 Sisällys Käsiteanalyysiä Tarkastellaan koodilukkoa äärellisenä automaattina. Deterministinen äärellinen

Lisätiedot

Lisää laskentoa. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Lisää laskentoa. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Lisää laskentoa TIEA341 Funktio ohjelmointi 1 Syksy 2005 Kertausta: Laajennettu aritmetiikka Lasketaan rationaaliluvuilla vakiot yhteen, vähennys, kerto ja jakolasku Laajennetaan sitä määrittelyillä: vakio

Lisätiedot

Ohjelmointi 1 Taulukot ja merkkijonot

Ohjelmointi 1 Taulukot ja merkkijonot Ohjelmointi 1 Taulukot ja merkkijonot Jussi Pohjolainen TAMK Tieto- ja viestintäteknologia Johdanto taulukkoon Jos ohjelmassa käytössä ainoastaan perinteisiä (yksinkertaisia) muuttujia, ohjelmien teko

Lisätiedot

Groovy. Niko Jäntti Jesper Haapalinna Group 31

Groovy. Niko Jäntti Jesper Haapalinna Group 31 Groovy Niko Jäntti Jesper Haapalinna Group 31 Johdanto Groovy on Apachen kehittämä Javaan perustuva dynaaminen oliopohjainen ohjelmointikieli. Kielen kehitys alkoi vuonna 2003, versio 1.0 julkaistiin 2007

Lisätiedot

etunimi, sukunimi ja opiskelijanumero ja näillä

etunimi, sukunimi ja opiskelijanumero ja näillä Sisällys 1. Algoritmi Algoritmin määritelmä. Aiheen pariin johdatteleva esimerkki. ja operaatiot (sijoitus, aritmetiikka ja vertailu). Algoritmista ohjelmaksi. 1.1 1.2 Algoritmin määritelmä Ohjelmointi

Lisätiedot

Harjoitus 1 -- Ratkaisut

Harjoitus 1 -- Ratkaisut Kun teet harjoitustyöselostuksia Mathematicalla, voit luoda selkkariin otsikon (ja mahdollisia alaotsikoita...) määräämällä soluille erilaisia tyylejä. Uuden solun tyyli määrätään painamalla ALT ja jokin

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2011 1 / 46 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

Olio-ohjelmointi Syntaksikokoelma

Olio-ohjelmointi Syntaksikokoelma C++-kielen uusia ominaisuuksia Olio-ohjelmointi Syntaksikokoelma 31.10.2008 Bool-tietotyyppi: Totuusarvo true (1), jos ehto on tosi ja false (0) jos ehto epätosi. Dynaaminen muistinvaraus: Yhden muuttuja

Lisätiedot

58131 Tietorakenteet ja algoritmit (syksy 2015)

58131 Tietorakenteet ja algoritmit (syksy 2015) 58131 Tietorakenteet ja algoritmit (syksy 2015) Harjoitus 2 (14. 18.9.2015) Huom. Sinun on tehtävä vähintään kaksi tehtävää, jotta voit jatkaa kurssilla. 1. Erään algoritmin suoritus vie 1 ms, kun syötteen

Lisätiedot

+ 3 2 5 } {{ } + 2 2 2 5 2. 2 kertaa jotain

+ 3 2 5 } {{ } + 2 2 2 5 2. 2 kertaa jotain Jaollisuustestejä (matematiikan mestariluokka, 7.11.2009, ohjattujen harjoitusten lopputuloslappu) Huom! Nämä eivät tietenkään ole ainoita jaollisuussääntöjä; ovatpahan vain hyödyllisiä ja ainakin osittain

Lisätiedot