815338A Ohjelmointikielten periaatteet

Samankaltaiset tiedostot
Funktionaalinen ohjelmointi

Funktionaalinen ohjelmointi

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet

Ohjelmoinnin peruskurssien laaja oppimäärä

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

Funktionaalinen ohjelmointi

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

Mitä funktionaalinen ohjelmointi on

TIEA341 Funktio-ohjelmointi 1, kevät 2008

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

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Ohjelmoinnin peruskurssien laaja oppimäärä

Luku 3. Listankäsittelyä. 3.1 Listat

811120P Diskreetit rakenteet

Scheme-kesäkurssi luento 2

Ohjelmoinnin peruskurssien laaja oppimäärä

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Ohjelmoinnin perusteet Y Python

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19

Ohjelmoinnin peruskurssien laaja oppimäärä

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Luento 5. Timo Savola. 28. huhtikuuta 2006

Scheme-kesäkurssi luento 5

815338A Ohjelmointikielten periaatteet

TIE Principles of Programming Languages. Seminaariesityksen essee. Ryhmä 18: Heidi Vulli, Joni Heikkilä

Jatkeet. TIES341 Funktio ohjelmointi 2 Kevät 2006

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Ruby. Tampere University of Technology Department of Pervasive Computing TIE Principles of Programming Languages

Scheme-kesäkurssi luento 3

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

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

815338A Ohjelmointikielten periaatteet

TIEA255 Tietotekniikan teemaseminaari ohjelmointikielet ja kehitysalustat. Antti-Juhani Kaijanaho. 16. helmikuuta 2011

Tutoriaaliläsnäoloista

Ohjelmoinnin peruskurssien laaja oppimäärä

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

Tietorakenteet ja algoritmit - syksy

ITKP102 Ohjelmointi 1 (6 op)

Clojure, funktionaalinen Lisp murre

Scheme-kesäkurssi luento 1

TIES542 kevät 2009 Tyyppijärjestelmän laajennoksia

Prolog kielenä Periaatteet Yhteenveto. Prolog. Toni ja Laura Fadjukoff. 9. joulukuuta 2010

Chomskyn hierarkia. tyyppi 0 on juuri esitelty (ja esitellään kohta lisää) tyypit 2 ja 3 kurssilla Ohjelmoinnin ja laskennan perusmallit

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

ITKP102 Ohjelmointi 1 (6 op)

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Tietueet. Tietueiden määrittely

Olio-ohjelmointi Syntaksikokoelma

Rekursiiviset tyypit

Ohjelmoinnin peruskurssi Y1

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

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Haskell ohjelmointikielen tyyppijärjestelmä

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Lisää pysähtymisaiheisia ongelmia

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

1. Olio-ohjelmointi 1.1

Ohjelmoinnin perusteet Y Python

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

Luku 5. Monadit. 5.1 Siirrännän ongelma

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

ITKP102 Ohjelmointi 1 (6 op)

Yhteydettömät kieliopit [Sipser luku 2.1]

14.1 Rekursio tyypitetyssä lambda-kielessä

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Vaihtoehtoinen tapa määritellä funktioita f : N R on

ELM GROUP 04. Teemu Laakso Henrik Talarmo

Rekursio. Funktio f : N R määritellään yleensä antamalla lauseke funktion arvolle f (n). Vaihtoehtoinen tapa määritellä funktioita f : N R on

on rekursiivisesti numeroituva, mutta ei rekursiivinen.

Ohjelmoinnin perusteet Y Python

Java-kielen perusteita

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 19. tammikuuta 2012

Python-ohjelmointi Harjoitus 5

Scheme-kesäkurssi luento 4

Transkriptio:

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 kieliä 6. Funktionaalisten ja imperatiivisten kielten vertailua 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 2

VI.1. Johdanto ja peruskäsitteitä Vaihtoehtoja imperatiiviselle ja olioparadigmalle: Funktionaalinen ohjelmointi ja logiikkaohjelmointi Yleisnimi deklaratiivinen ohjelmointi Joissakin lähteissä vain logiikkaohjelmointi deklaratiivista Imperatiivisten ohjelmointikielten tunnusmerkit Perustuvat von Neumannin arkkitehtuuriin Fyysisiin muistipaikkoihin sidottujen muuttujien käyttö Sijoituslause Iteratiivisen toiston tehokas soveltaminen 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 3

VI.1. Johdanto ja peruskäsitteitä (2) Funktionaalinen ohjelmointi Luovutaan komennoista Suoritetaan operaatiot lausekkeita käyttämällä, erityisesti funktioita toistuvasti soveltamalla Funktiot peruselementtejä Vastaavat muuttujia imperatiivisessa ohjelmoinnissa Ei sijoituslausetta Toisto tyypillisesti rekursiolla Monissa funktionaalisissa kielissä imperatiivisia piirteitä 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 4

VI.1.1. Matemaattiset funktiot ja korkeamman asteen funktiot (higher order functions) Matemaattisella funktiolla ei voi olla sivuvaikutuksia Ero imperatiivisen ohjelmoinnin funktioon Ainoa toimenpide palauttaa argumenttia vastaava arvo, joka on aina samalla argumentin arvolla sama Korkeamman asteen funktioita kutsutaan myös funktionaalisiksi muodoiksi (functional forms) Voivat ottaa parametreikseen funktioita Paluuarvo voi olla funktio 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 5

VI.1.2. Tavallisia funktionaalisia muotoja Funktioiden yhdistäminen (kompositio) Funktioiden f ja g yhdistetty funktio h = f g; h(x) = f(g(x)) Esimerkki. Jos f(x) = x 2 ja g(x) = 2x+1, h(x) = f g(x) = f(g(x)) = f(2x+1) = (2x+1) 2 = 4x 2 + 4x +1 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 6

VI.1.2. Tavallisia funktionaalisia muotoja (2) *x++=*y++ Konstruktio saadaan soveltamalla annetun funktiolistan jokaista funktiota yhteen argumenttiin: saadaan arvojen lista, jossa on yhtä monta alkioita kuin funktioita oli listassa Esimerkki f(x) = 3x-1 ja g(x) = x 4 +2 [f,g](3) tuottaa listan (8,83) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 7

VI.1.2. Tavallisia funktionaalisia muotoja (3) Sovella kaikkiin: Sovelletaan samaa funktiota listan kaikkiin alkioihin Merkitään symbolilla α Esimerkki f(x) = x/3 -> operaation α(f,(1,2,3)) tuloksena (1/3,2/3,1) *x++=*y++ 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 8

VI.1.3 Funktionaalisen ohjelmoinnin peruskäsitteitä Viittauksen läpinäkyvyys (referential transparency): Funktio antaa samoilla parametreilla aina saman tuloksen Käytetään myös nimityksiä viite-eheys, viittausten läpikuultavuus Tiukka semantiikka (strict semantics) Funktiota ei evaluoida ennen kuin sen parametrit on täysin evaluoitu Noudatetaan yleensä imperatiivisissa ja useissa funktionaalisissa kielissä Ellei voimassa, semantiikka joustava (non-strict) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 9

VI.1.3 Funktionaalisen ohjelmoinnin peruskäsitteitä (2) Innokas evaluointi (eager evaluation) : funktion ja lausekkeen arvo lasketaan välittömästi sen parametrien kulloisillakin arvoilla Käytetään kaikissa imperativiisissa ja monissa funktionaalisissa kielissä Laiska evaluointi (lazy evaluation): lausekkeen arvo evaluoidaan vasta kun sitä tarvitaan ja evaluointi tapahtuu ainoastaan kerran Mahdollinen jos semantiikka joustava Mahdollistaa näennäisesti äärettömien rakenteiden kirjoittamisen 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 10

VI.2. LISP- ja Scheme-kielet VI.2.1 LISP *x++=*y++ John McCarthy: LISP vuonna 1958 MIT:n tekoälyprojektin yhteydessä Haluttiin kieli, jolla vahva matemaattinen pohja McCarthy: rekursiivisten funktioiden teoria soveltuu perustaksi paremmin kuin Turingin koneeseen perustuvat mallit Mahdollisuus listojen käsittelyyn Funktion käsitteen mahdollisimman laaja soveltaminen 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 11

VI.2.1 LISP (2) McCarthy: LISPin yleisfunktio eval, joka laskee minkä tahansa LISP-funktion arvon -> Ensimmäinen LISP tulkki kun huomattiin, että implementoituna voidaan käyttää tulkkina Ensimmäinen kääntäjä toteutettiin LISPillä Tiettävästi ensimmäinen kerta, kun kielen kääntäjä kirjoitetaan samalla kielellä LISPistä monia murteita, COMMON LISP ja Scheme yleisimmin käytössä Tässä esitettävät ominaisuudet koskevat myös Schemeä 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 12

VI.2.1.1 LISPin symbolit Koostuvat kirjaimista, numeroista ja eräistä sallituista erikoismerkeistä Luvut eivät ole symboleja, koska ne aina edustavat ainoastaan numeerista arvoaan Symboleilla T ja NIL erikoismerkitys: T on totuusarvo tosi ja NIL epätosi Loogisissa lausekkeissa NIL on epätosi ja mikä tahansa siitä poikkeava arvo katsotaan todeksi Schemessä totuusarvot #t ja #f Symbolit ja luvut = atomit (atoms) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 13

VI.2.1.2 LISPin perustietotyypit Atomit (atoms) ja listat (lists) Lista on järjestetty joukko, jonka alkiot ovat atomeja tai toisia listoja Listan rajoittimina toimivat kaarisulut ja alkioiden erottimina sanavälit Lista voi olla tyhjä, merkitään ( ) tai NIL Schemessä null Atomit ja listat = symboliset lausekkeet tai s- lausekkeet (s-expression) Listan ensimmäinen alkio on sen pää (head) ja kaikki loput sen häntä (tail) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 14

VI.2.1.3. LISPin funktiot Kirjoitetaan listamuodossa (funktio parametri1 parametri2...) Noudattaa tiukkaa semantiikkaa Funktion nimi kirjoitetaan aina ensin Esimerkki. Operaatio 2+3 kirjoitetaan (+ 2 3) ja 3*4+5 (+ (* 3 4) 5) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 15

VI.2.1.3. LISPin funktiot (2) QUOTE ( ) Lauseke LISP tulkille -> määrää lausekkeen arvon laskemalla uloimman funktion kutsun argumenttien arvot vasemmalta oikealle Jos halutaan lauseke sellaisenaan, merkitään lainaukseksi kirjoittamalla tai QUOTE lausekkeen eteen, esimerkiksi (+ 3 4) ei laske arvoa 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 16

VI.2.2 Scheme 1970-luvun puolivälissä syntynyt LISPin murre Pieni ja kompakti Syntaksi ja semantiikka yksinkertaisia Suunnittelussa minimalistinen idea Käytetty ohjelmoinnin opettamisessa 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 17

VI.2.2.1 Funktioiden määrittely Schemessä *x++=*y++ Funktionaalisessa kielessä oltava mahdollisuus määritellä omia funktioita Lambda-lausekkeet Käytetään Schemessä funktioiden määrittelyyn (LAMBDA (x) (* x x)) Parametrien lista = lambda-lista Yleinen laskenta lambda-lauseen rungossa (yllä (* x x)) Abstrakti mekanismi funktion määrittelyä ja laskentaa varten; nimetön funktio, häviää kun muoto on laskettu -> tarvitaan mekanismi, jolla funktioon voidaan sitoa tunniste 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 18

VI.2.2.1 Funktioiden määrittely Schemessä (2) Uusien funktioiden määrittely tapahtuu funktiolla define Esimerkki. Edellinen funktio voidaan määritellä (define nelio (x) (* x x) ) -> voidaan ohjelmassa kutsua nimellä: (nelio 5) -> 25 *x++=*y++ 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 19

VI.2.2.2 Schemen kontrollirakenteet Muistuttavat ulkoisesti funktiokutsuja Sulkulausekkeita: ensimmäinen termi ohjausrakenteen nimi; seuraavat ikään kuin funktion argumentteja, joihin rakennetta sovelletaan Rakenteen laskennan tuloksena jokin arvo kuten funktioilla 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 20

VI.2.2.2 Schemen kontrollirakenteet (2) if-lause Kahden vaihtoehdon ehtolause, muoto: (if ehto tosi-muoto epätosi-muoto) Esimerkki. Kertoma-funktio (define (kertoma n) (if (<= n 1) 1 (* n (kertoma (- n 1))))) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 21

VI.2.2.2 Schemen kontrollirakenteet (3) cond-lause: monivalintarakenne Haarauttaa laskentaa predikaattien määrittelemien ehtojen nojalla, lauseen muoto: (cond (p1 a1) (p2 a2) (pn an) (else a)) Predikaatit pi ja arvolausekkeet ai ja a mielivaltaisia muotoja Arvoksi ensimmäistä tosi-arvoista predikaattia vastaava arvo tai elseä vastaava arvo. Else ei pakollinen -> lauseen arvo voi olla epämääräinen 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 22

VI.2.2.2 Schemen kontrollirakenteet (4) Esimerkki cond-lauseesta: Fibonaccin lukuja palauttava funktio (define (fibo n) (cond ((= n 0) 0) )) ((= n 1) 1) (else (+ (fibo (- n 1)) (fibo (- n 2)))) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 23

VI.2.2.3 Schemen listankäsittelyfunktioita Listojen käsittelyn neljä alkeisfunktiota car, cdr, cons, ja list car ja cdr listan purkufunktioita car palauttaa argumenttina saadun listan pään ja cdr listan hännän -> Funktion car paluuarvo on s- lauseke ja funktion CDR paluuarvo lista Esimerkki (car (a b c d) ) -> s-lauseke a ja (cdr (a b c d) ) -> lista (b c d) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 24

VI.2.2.3 Schemen listankäsittelyfunktioita (2) cons ja list listan muodostajia cons lisää ensimmäisen argumentin toisen listaargumentin alkuun. Esimerkiksi (cons 'C '(A B)) -> lista (C A B) *x++=*y++ list muodostaa listan parametreistansa. Esimerkiksi (list 'C '(A B) 'D) -> lista (C (A B) D) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 25

VI.2.2.3 Schemen listankäsittelypredikaatteja eq?, null? ja list? Schemen listojen käsittelyn alkeispredikaatit list? : Onko parametri lista vai ei null? : Onko parametrilista tyhjä vai ei eq? : Vertailee ovatko parametrisymbolit samat. Ei toimi järkevästi listoille *x++=*y++ 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 26

VI.2.2.4 Scheme-esimerkkejä Tehtävä: Kirjoita funktio onko_jasen, joka päättelee, onko parametrina saatu alkio toisena parametrina saadun listan alkio. Paluuarvona #t tai #f. Ratkaisun idea: Jos lista on tyhjä palautetaan #f Jos alkio löytyy listan päästä #t Muuten kutsutaan samaa funktiota listan häntä parametrina -> Lista lyhenee -> Rekursio päättyy 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 27

VI.2.2.4 Scheme-esimerkkejä (2) Ratkaisufunktio: (define (onko_jasen x lista) (cond ((null? lista) #f) ((eq? (car lista) x) #t) (else (onko_jasen x (cdr lista))) )) Esimerkkejä toiminnasta: (onko_jasen 'a '(b a c)) -> #t (onko_jasen 'a '(b (a c) d)) -> #f Ei tutki sisältyykö alilistoihin 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 28

VI.2.2.4 Scheme-esimerkkejä (3) Tehtävä: Kirjoita funktio litista, joka litistää parametrina saadun listan, ts. poistaa kaikki muut paitsi uloimmat sulut. Apuna voi käyttää Schemen varusfunktiota append, joka yhdistää parametreinaan saadut kaksi listaa Ratkaisuidea: Jos lista on tyhjä, palautetaan tyhjä lista Jos parametri on atomi, siitä muodostetaan yksialkioinen lista Muuten litistetään listan ensimmäinen alkio ja listan häntä sekä yhdistetään saadut listat Sovelletaan lyheneviin listoihin -> rekursio päättyy 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 29

VI.2.2.4 Scheme-esimerkkejä (4) Ratkaisufunktio: (define (litista lista) (cond ((null? lista) '() ) ((not (list? lista)) (cons lista '())) (else (append (litista (car lista)) (litista (cdr lista)))))) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 30

VI.3. Haskell Julkaistu vuonna 1987 Nimetty matemaatikko Haskell Brooks Curryn mukaan Puhtaasti funktionaalinen kieli Ehkä yleisin käytössä Vahva tyypitys Laiska evaluointi Syntaksi muistuttaa ML-kieltä Yhteisiä piirteitä ML:n kanssa vahva tyypitys ja moduulirakenne Toteutuksia vapaasti saatavilla https://www.haskell.org/ 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 31

VI.3.1 Haskellin funktiot Voidaan määritellä hahmontunnistuksella Esimerkki. Kertoma-funktio kertoma 0 = 1 kertoma n = n * kertoma(n-1) Ehtolauseen käyttäminen määrittelyssä kertoma(n) = if n == 0 then 1 else n*kertoma(n-1) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 32

VI.3.1 Haskellin funktiot (2) Esimerkki. Vaihtoehtorakenteen käyttö Fibonacci-lukuja laskevan funktion määrittelyssä fibo n n == 0 = 0 n == 1 = 1 n > 1 = fibo(n-1)+fibo(n-2) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 33

VI.3.1 Haskellin listat Esitetään hakasulkeiden sisällä, alkiot pilkulla erotettuna suunnat = [ N, S, E, W ] Listojen yhdistäminen: operaattori ++ [1,4,5] ++ [2,6,8] -> [1,4,5,2,6,8] Kaksoispisteellä merkitään osa listasta -> Funktio joka palauttaa listan pituuden pituus [] = 0 pituus(x:xs) = 1 + pituus(xs) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 34

VI.3.1 Haskellin listat (2) Listakehitelmillä (list comprehensions) voidaan määritellä listoja. Muoto [runko määreet] Esimerkki. Lista [1,4,9,16,,400] [n*n n <- [1..20]] Laiskan evaluoinnin ansiosta voi olla potentiaalisesti ääretön: parilliset = [2, 4..] neliot = [n*n n <- parilliset] Listassa periaatteessa kaikkien parillisten lukujen neliöt. Listaa muodostetaan käytettäessä niin pitkälle kuin tarvitaan 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 35

VI.3.2 Haskell-esimerkkejä Kirjoita Haskell-funktio, joka lajittelee listan Quicksortalgoritmilla Ratkaisu: Quicksort lajittelee listan hakemalla listan ensimmäiselle alkiolle oikean paikan listassa ja lajittelemalla rekursiivisesti vasemman ja oikean puolen -> ratkaisufunktio q_sort [] = [] q_sort (x:xs) = q_sort [z z <- xs, z <= x] ++ [x] ++ q_sort [z z <- xs, z > x] 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 36

VI.3.2 Haskell-esimerkkejä (2) Kirjoita Haskell-funktio, joka tutkii, onko syötejono palindromi, kun jonosta poistetaan valkomerkit eikä tehdä eroa isojen ja pienten kirjainten välillä Ratkaisu: Käytetään apuna Haskell-funktioita isalpha, joka tutkii onko merkki kirjain ja tolower joka muuttaa kirjainmerkin pieneksi. Näiden, sekä Haskell-funktioiden filter ja map avulla puhdistetaan syöte ja tutkitaan onko puhdistettu syöte käännettynä sama kuin puhdistettu syöte 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 37

VI.3.2 Haskell-esimerkkejä (3) Palindromin testaus -- tuodaan merkkifunktiot import Data.Char (tolower,isalpha) putsaa str = filter isalpha str pieneksi str = map tolower str kaanna [] = [] kaanna (x:xs) = kaanna(xs) ++ [x] -- varsinainen testifunktio onkopalindromi str = (m_str == (kaanna m_str)) where m_str = pieneksi (putsaa str) 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 38

VI.4. IO funktionaalisissa kielissä Sivuvaikutuksien takia IO:n toteuttaminen funktionaalisessa ohjelmoinnissa periaatteessa hankalaa Yleisimmin tietovirtojen (streams) avulla Virta laiskasti evaluoitava rajoittamattoman pituinen lista: kun tarvitaan syötettä, evaluoidaan listan pää Haskellissa listojen alkiot samaa tyyppiä -> erityyppisten syötteiden käsittely ongelmallista Haskellissa monadijärjestelmä: toimintoja (actions) voidaan ketjuttaa ja liittää niihin piilotettu tila Joissakin kielissä (esim. Clean) tyyppijärjestelmää laajennettu Uniqueness types: voidaan viitata vain kerran 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 39

VI.5. Muita funktionaalisia kieliä COMMON LISP (1984) Yhdistelmä LISPin murteista -> varsin laaja Sekä dynaaminen että staattinen näkyvyysalueen määräytyminen ML (MetaLanguage, 1973) Syntaksi muistuttaa enemmän Pascalia kuin LISPiä Sisältää imperatiivisia piirteitä Tyypit voidaan esitellä tai määräytyvät implisiittisesti Vahvasti tyypitetty staattinen tyypintarkistus -> luotettavuus ja tehokkuus lisääntyvät Moduuliominaisuus -> abstraktit tietotyypit 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 40

VI.5. Muita funktionaalisia kieliä (2) F# (2005) Kuuluu MS:n.NET-perheeseen Sisältää imperatiivisia piirteitä Tukee olio-ohjelmointia Funktiot muistuttavat Haskellin funktioita 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 41

VI.6 Funktionaalisten ja imperatiivisten kielten vertailua *x++=*y++ Kielen syntaksi ja semantiikka funktionaalisissa kielissä yksinkertaisempi Kiistanalaista kumman paradigman ohjelmointi tuottavampaa Todennäköisesti riippuu sovelluskohteesta Imperatiiviset ohjelmat tehokkaampia Ero ei kaikissa sovelluksissa merkittävä Luettavuus: Funktionaalinen koodi yleensä helpommin tulkittavissa Suuri suosioero imperatiivisten kielten hyväksi ehkä tottumuskysymys? 815338A Ohjelmointikielten periaatteet, Funktionaalinen ohjelmointi 42