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 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 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

Laajennetaan vielä Ydin-Haskellia ymmärtämään vakiomäärittelyt. Määrittely on muotoa

Laajennetaan vielä Ydin-Haskellia ymmärtämään vakiomäärittelyt. Määrittely on muotoa 2.6. TIETOKONE LASKIMENA 23 Edellä esitetty Ydin-Haskell on hyvin lähellä sitä kieltä, jota GHCi (Glasgow Haskell Compiler, Interactive) sekä muut Haskell-järjestelmät suostuvat ymmärtämään. Esimerkiksi:

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

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

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA34 Funktio-ohjelmointi, kevät 2008 Luento 3 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 2. tammikuuta 2008 Ydin-Haskell: Syntaksi Lausekkeita (e) ovat: nimettömät funktiot: \x

Lisätiedot

JFO: Johdatus funktionaaliseen ohjelmointiin

JFO: Johdatus funktionaaliseen ohjelmointiin JFO: Johdatus funktionaaliseen ohjelmointiin Matti Nykänen Tietojenkäsittelytieteen laitos, Itä-Suomen yliopisto matti.nykanen@uef.fi Lukuvuosi 2010-11, IV periodi Sisältö 1 Johdanto 1 1.1 Historiaa.....................................

Lisätiedot

Haskell ohjelmointikielen tyyppijärjestelmä

Haskell ohjelmointikielen tyyppijärjestelmä Haskell ohjelmointikielen tyyppijärjestelmä Sakari Jokinen Helsinki 19. huhtikuuta 2004 Ohjelmointikielten perusteet - seminaarityö HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos 1 Johdanto 1 Tyyppien

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

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, literaalivakio, nimetty vakio Tiedon merkkipohjainen tulostaminen 1 Tunnus Java tunnus Java-kirjain Java-numero

Lisätiedot

2.4 Normaalimuoto, pohja ja laskentajärjestys 2.4. NORMAALIMUOTO, POHJA JA LASKENTAJÄRJESTYS 13

2.4 Normaalimuoto, pohja ja laskentajärjestys 2.4. NORMAALIMUOTO, POHJA JA LASKENTAJÄRJESTYS 13 2.4. NORMAALIMUOTO, POHJA JA LASKENTAJÄRJESTYS 13 Toisinaan voi olla syytä kirjoittaa α- tai β-kirjain yhtäsuuruusmerkin yläpuolelle kertomaan, mitä muunnosta käytetään. Esimerkki 4 1. (λx.x)y β = y 2.

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

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

Laiska laskenta, korekursio ja äärettömyys. TIEA341 Funktio ohjelmointi Syksy 2005

Laiska laskenta, korekursio ja äärettömyys. TIEA341 Funktio ohjelmointi Syksy 2005 Laiska laskenta, korekursio ja äärettömyys TIEA341 Funktio ohjelmointi Syksy 2005 Muistatko graafinsievennyksen? DAG esitys ja graafinsievennys DAG esitys Lausekkeen rakennepuu, jossa yhteiset alilausekkeet

Lisätiedot

Turingin koneet määritteli sen laitelähtöisesti: Laskenta etenee suorittamalla yksinkertaisia käskyjä siten kuin sen ohjelma

Turingin koneet määritteli sen laitelähtöisesti: Laskenta etenee suorittamalla yksinkertaisia käskyjä siten kuin sen ohjelma 1 Johdanto Aloitetaan lyhyellä kuvauksella funktionaalisen ohjelmoinnin ja siihen kannustavien ohjelmointikielten historiasta. Sitten kuvaillaan lyhyesti, mitä funktionaalisella ohjelmoinnilla tarkoitetaan

Lisätiedot

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin Raimo Nikkilä Aalto-yliopiston sähkötekniikan korkeakoulu - Automaation tietotekniikan tutkimusryhmä 17. tammikuuta 2013

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 10 Todistamisesta Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Samuuden todistaminen usein onnistuu ihan laskemalla

Lisätiedot

TIES542 kevät 2009 Tyyppijärjestelmän laajennoksia

TIES542 kevät 2009 Tyyppijärjestelmän laajennoksia TIES542 kevät 2009 Tyyppijärjestelmän laajennoksia Antti-Juhani Kaijanaho 16. helmikuuta 2009 Tyypitetyt ohjelmointikielet sisältävät paljon muitakin konstruktioita kuin yksinkertaisesti tyypitetyn lambda-kielen,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 21.1.2009 T-106.1208 Ohjelmoinnin perusteet Y 21.1.2009 1 / 32 Tyypeistä Monissa muissa ohjelmointikielissä (esim. Java ja C) muuttujat on määriteltävä ennen

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 7: Funktionaalista ohjelmointia (mm. SICP 3.5) Riku Saikkonen 13. 11. 2012 Sisältö 1 Laiskaa laskentaa: delay ja force 2 Funktionaalinen I/O 3 Funktionaalista

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

Tietorakenteet ja algoritmit - syksy 2015 1

Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 2 Tietorakenteet ja algoritmit Johdanto Ari Korhonen Tietorakenteet ja algoritmit - syksy 2015 1. JOHDANTO 1.1 Määritelmiä

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 10. tammikuuta 2008 Arvot... ovat laskutoimituksen lopputuloksia... ovat lausekkeita, joihin

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 9 Kombinaattoreista Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Currying Haskell-funktio ottaa aina vain yhden

Lisätiedot

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari 1 1. JOHDANTO 1.1 Määritelmiä 1.2 Tietorakenteen ja algoritmin valinta 1.3 Algoritmit ja tiedon määrä 1.4 Tietorakenteet ja toiminnot 1.5 Esimerkki:

Lisätiedot

Koka. Ryhmä 11. Juuso Tapaninen, Akseli Karvinen. 1. Taustoja 2. Kielen filosofia ja paradigmat 3. Kielen syntaksia ja vertailua JavaScriptiin Lähteet

Koka. Ryhmä 11. Juuso Tapaninen, Akseli Karvinen. 1. Taustoja 2. Kielen filosofia ja paradigmat 3. Kielen syntaksia ja vertailua JavaScriptiin Lähteet 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ä

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

Ohjelmoinnin perusteet Y Python

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

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

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

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

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

Kielioppia: toisin kuin Javassa

Kielioppia: toisin kuin Javassa Object Pascal Pascal kielen oliolaajennus (Inprise/Borland:n oma) luokat Voit uudelleenkäyttää luomiasi objekteja esim. komponentteja Periytyminen Kielioppia: toisin kuin Javassa Ei eroa isojen ja pienien

Lisätiedot

Lisää pysähtymisaiheisia ongelmia

Lisää pysähtymisaiheisia ongelmia Lisää pysähtymisaiheisia ongelmia Lause: Pysähtymättömyysongelma H missä H = { w111x w validi koodi, M w ei pysähdy syötteellä x } ei ole rekursiivisesti lueteltava. Todistus: Pysähtymisongelman komplementti

Lisätiedot

Ohjelmoinnin peruskurssi Y1

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

Lisätiedot

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit IDL - proseduurit 25. huhtikuuta 2017 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

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

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 2: SICP kohdat 22.2.3 Riku Saikkonen 2. 11. 2010 Sisältö 1 Linkitetyt listat 2 Listaoperaatioita 3 Listarakenteet 4 Gambit-C:n Scheme-debuggeri Linkitetyt

Lisätiedot

Tutoriaaliläsnäoloista

Tutoriaaliläsnäoloista Tutoriaaliläsnäoloista Tutoriaaliläsnäolokierroksella voi nyt täyttää anomuksen läsnäolon merkitsemisestä Esim. tagi ei toiminut, korvavaltimon leikkaus, yms. Hyväksyn näitä omaa harkintaa käyttäen Tarkoitus

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

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

Geneeriset tyypit. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos Geneeriset tyypit TIES542 Ohjelmointikielten periaatteet, kevät 2007 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 6. maaliskuuta 2007 Kysymys Mitä yhteistä on seuraavilla funktioilla?

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

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 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

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen Metodit Metodien määrittely Metodin parametrit ja paluuarvo Metodien suorittaminen eli kutsuminen Metodien kuormittaminen 1 Mikä on metodi? Metodi on luokan sisällä oleva yhteenkuuluvien toimintojen kokonaisuus

Lisätiedot

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä Rekursiolause Laskennan teorian opintopiiri Sebastian Björkqvist 23. helmikuuta 2014 Tiivistelmä Työssä käydään läpi itsereplikoituvien ohjelmien toimintaa sekä esitetään ja todistetaan rekursiolause,

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 8: Pienen ohjelmointikielen tulkki (ohjelmoitava laskin) (mm. SICP 4-4.1.5 osin) Riku Saikkonen 15. 11. 2012 Sisältö 1 Nelilaskintulkki, globaalit muuttujat

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

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

Rekursiiviset palautukset [HMU 9.3.1]

Rekursiiviset palautukset [HMU 9.3.1] Rekursiiviset palautukset [HMU 9.3.1] Yleisesti sanomme, että ongelma P voidaan palauttaa ongelmaan Q, jos mistä tahansa ongelmalle Q annetusta ratkaisualgoritmista voidaan jotenkin muodostaa ongelmalle

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

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

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

Tietueet. Tietueiden määrittely

Tietueet. Tietueiden määrittely Tietueet Tietueiden määrittely Tietue on tietorakenne, joka kokoaa yhteen eri tyyppistä tietoa yhdeksi asiakokonaisuudeksi. Tähän kokonaisuuteen voidaan viitata yhteisellä nimellä. Auttaa ohjelmoijaa järjestelemään

Lisätiedot

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python 8. marraskuuta 2010 Ohjelmointi Perusteet Peruskäsitteitä Olio-ohjelmointi Pythonin alkeet Esittely Esimerkkejä Muuttujat

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

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

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 25.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 25.2.2009 1 / 34 Syötteessä useita lukuja samalla rivillä Seuraavassa esimerkissä käyttäjä antaa useita lukuja samalla

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 11 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Listakomprehensio Uusi tapa luoda (ja muokata) listoja: [ lauseke

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 3: Funktionaalinen listankäsittely ja listankäsittelyoperaatiot (mm. SICP 22.2.3) Riku Saikkonen 31. 10. 2011 Sisältö 1 Linkitetyt listat 2 Listarakenteet

Lisätiedot

8.5 Takarekursiosta. Sanoimme luvun 8.3 foldl -esimerkissämme että

8.5 Takarekursiosta. Sanoimme luvun 8.3 foldl -esimerkissämme että 85 Takarekursiosta Sanoimme luvun 83 foldl -esimerkissämme että foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs olisi pelkkä silmukka Tämä johtuu siitä, että

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

815338A Ohjelmointikielten periaatteet 2014-2015

815338A Ohjelmointikielten periaatteet 2014-2015 815338A Ohjelmointikielten periaatteet 2014-2015 X Skriptiohjelmointi Sisältö 1. Johdanto 2. Skriptikielten yleispiirteitä 3. Python 815338A Ohjelmointikielten periaatteet, Skriptiohjelmointi 2 X.1 Johdanto

Lisätiedot

Luku 2. Ohjelmointi laskentana. 2.1 Laskento

Luku 2. Ohjelmointi laskentana. 2.1 Laskento Luku 2 Ohjelmointi laskentana Funktio-ohjelmoinnin, olio-ohjelmoinnin ja käskyohjelmoinnin ero on löydettävissä niiden pohjalla olevista laskennan mallista. Automaattisen tietojenkäsittelyn yksi historiallinen

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 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

Ohjelmointitaito (ict1td002, 12 op) Kevät 2008. 1. Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen raine.kauppinen@haaga-helia.

Ohjelmointitaito (ict1td002, 12 op) Kevät 2008. 1. Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen raine.kauppinen@haaga-helia. Ohjelmointitaito (ict1td002, 12 op) Kevät 2008 Raine Kauppinen raine.kauppinen@haaga-helia.fi 1. Java-ohjelmoinnin alkeita Tietokoneohjelma Java-kieli ja Eclipse-ympäristö Java-ohjelma ja ohjelmaluokka

Lisätiedot

Tämä tarina on Fibonaccin lukujen ongelman alkuperäinen muotoilu.

Tämä tarina on Fibonaccin lukujen ongelman alkuperäinen muotoilu. Rekursiosta ja iteraatiosta Oletetaan että meillä on aluksi yksi vastasyntynyt kanipari, joista toinen on uros ja toinen naaras. Kanit saavuttavat sukukypsyyden yhden kuukauden ikäisinä. Kaninaaraan raskaus

Lisätiedot

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A. Tehtävä. Tämä tehtävä on aineistotehtävä, jossa esitetään ensin tehtävän teoria. Sen jälkeen esitetään neljä kysymystä, joissa tätä teoriaa pitää soveltaa. Mitään aikaisempaa tehtävän aihepiirin tuntemusta

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

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 peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 11: Tulkin muokkaaminen, sisäiset määrittelyt, makrot (mm. SICP 3.2.4, 4-4.1.6) Riku Saikkonen 29. 11. 2012 Sisältö 1 Kirjan tulkin muokkaaminen 2 Yksityiskohta:

Lisätiedot

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python 31. tammikuuta 2009 Ohjelmointi Perusteet Pythonin alkeet Esittely Esimerkkejä Muuttujat Peruskäsitteitä Käsittely

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2009 1 / 35 Listat Esimerkki: halutaan kirjoittaa ohjelma, joka lukee käyttäjältä 30 lämpötilaa. Kun lämpötilat

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 6: Funktionaalista ohjelmointia: todistamisesta, virrat ja I/O, hahmonsovitus (mm. SICP 3.5) Riku Saikkonen 8. 11. 2011 Sisältö 1 Vähän funktionaalisten

Lisätiedot

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet 811120P Diskreetit rakenteet 2016-2017 4. Joukot, relaatiot ja funktiot Osa 3: Funktiot 4.3 Funktiot Olkoot A ja B joukkoja. Funktio joukosta A joukkoon B on sääntö, joka liittää yksikäsitteisesti määrätyn

Lisätiedot

Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005

Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005 Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005 Esimerkki: Laskin Liukulukulaskentaa Yhteen, vähennys, kerto ja jakolaskut Syötteenä laskutehtävä, tulosteena tulos tai virheilmoitus

Lisätiedot

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti C! Perusteet 19.1.2017 Palautteesta (1. kierros toistaiseksi) (Erittäin) helppoa Miksi vain puolet pisteistä? Vaikeinta oli ohjelmointiympäristön asennus ja käyttö Ei selvää että main funktion pitikin

Lisätiedot

1 Mitä funktionaalinen ohjelmointi on?

1 Mitä funktionaalinen ohjelmointi on? 1 Mitä funktionaalinen ohjelmointi on? On olemassa useita erilaisia ohjelmointiparadigmoja (programming paradigms) koska on useita erilaisia tapoja mallintaa ohjelmointiongelmia, esimerkiksi: Proseduraalinen

Lisätiedot

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 31. maaliskuuta 2011

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 31. maaliskuuta 2011 TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 31. maaliskuuta 2011 Sisällys Sisällys Chomskyn hierarkia kieli säännöllinen kontekstiton kontekstinen rekursiivisesti

Lisätiedot

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne.

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne. Proseduurit Proseduuri voi olla 1) Funktio, joka palauttaa jonkin arvon: real function sinc(x) real x sinc = sin(x)/x... y = sinc(1.5) 2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma

Lisätiedot

Osoitin ja viittaus C++:ssa

Osoitin ja viittaus C++:ssa Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 4: Symbolit, derivojaesimerkki, kierroksen 1 ratkaisut (mm. SICP 2.32.3.2) Riku Saikkonen 1. 11. 2011 Sisältö 1 Symbolit ja sulkulausekkeet 2 Lisää Schemestä:

Lisätiedot

Java-kielen perusteita

Java-kielen perusteita Java-kielen perusteita valintalauseet 1 Johdantoa kontrollirakenteisiin Tähän saakka ohjelmissa on ollut vain peräkkäisyyttä eli lauseet on suoritettu peräkkäin yksi kerrallaan Tarvitsemme myös valintaa

Lisätiedot

Zeon PDF Driver Trial

Zeon PDF Driver Trial Matlab-harjoitus 2: Kuvaajien piirto, skriptit ja funktiot. Matlabohjelmoinnin perusteita Numeerinen integrointi trapezoidaalimenetelmällä voidaan tehdä komennolla trapz. Esimerkki: Vaimenevan eksponentiaalin

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

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

Tietorakenteet (syksy 2013)

Tietorakenteet (syksy 2013) Tietorakenteet (syksy 2013) Harjoitus 1 (6.9.2013) Huom. Sinun on osallistuttava perjantain laskuharjoitustilaisuuteen ja tehtävä vähintään kaksi tehtävää, jotta voit jatkaa kurssilla. Näiden laskuharjoitusten

Lisätiedot

5.5 Jäsenninkombinaattoreista

5.5 Jäsenninkombinaattoreista 5.5. JÄSENNINKOMBINAATTOREISTA 67 type Env α = FiniteMap String α data EnvT m α = MkE (Env Integer m (Env Integer, α)) instance Transformer EnvT where promote mp = MkE $ λenv mp λr return $(env, r) instance

Lisätiedot

Luento 5. Timo Savola. 28. huhtikuuta 2006

Luento 5. Timo Savola. 28. huhtikuuta 2006 UNIX-käyttöjärjestelmä Luento 5 Timo Savola 28. huhtikuuta 2006 Osa I Shell-ohjelmointi Ehtolause Lausekkeet suoritetaan jos ehtolausekkeen paluuarvo on 0 if ehtolauseke then lauseke

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

Harjoitus 3 (viikko 39)

Harjoitus 3 (viikko 39) Mikäli tehtävissä on jotain epäselvää, laita sähköpostia vastuuopettajalle (jorma.laurikkala@uta.fi). Muista nimetä muuttujat hyvin sekä kommentoida ja sisentää koodisi. Vältä liian pitkiä rivejä. Ohjelmointitehtävien

Lisätiedot