TIE Ohjelmistojen suunnittelu

Samankaltaiset tiedostot
TIE Ohjelmistojen suunnittelu

C++11 lambdat: [](){} Matti Rintala

12 Mallit (Templates)

Olio-ohjelmointi Syntaksikokoelma

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

Demo 6 vastauksia. 1. tehtävä. #ifndef #define D6T1 H D6T1 H. #include <iostream> using std::ostream; using std::cout; using std::endl;

C++11 Syntaksi. Jari-Pekka Voutilainen Jari-Pekka Voutilainen: C++11 Syntaksi

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

13 Operaattoreiden ylimäärittelyjä

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

15. Ohjelmoinnin tekniikkaa 15.1

Osoitin ja viittaus C++:ssa

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19

Metodien tekeminen Javalla

Lyhyt kertaus osoittimista

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

15. Ohjelmoinnin tekniikkaa 15.1

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

ITKP102 Ohjelmointi 1 (6 op)

TIE Ohjelmistojen suunnittelu. Kopiointia ja sijoittelua

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

ELM GROUP 04. Teemu Laakso Henrik Talarmo

Metaohjelmointia ja muuta hauskaa

ITKP102 Ohjelmointi 1 (6 op)

Geneeriset luokat. C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet. Geneerisen luokan käyttö.

4. Luokan testaus ja käyttö olion kautta 4.1

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

Tietueet. Tietueiden määrittely

11/20: Konepelti auki

815338A Ohjelmointikielten periaatteet

Javan perusteita. Janne Käki

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

TIE Ohjelmistojen suunnittelu. Kopiointia ja sijoittelua

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

1. Omat operaatiot 1.1

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

Rajapinta (interface)

Funktiomallit Funktiomallin määrittely

7. Oliot ja viitteet 7.1

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout:

ITKP102 Ohjelmointi 1 (6 op)

TIE Ohjelmistojen suunnittelu

TIE Ohjelmistojen suunnittelu. Luento 8..9: moniperintä

Ohjelmointi 1 Taulukot ja merkkijonot

Olio-ohjelmointi Javalla

19. Olio-ohjelmointia Javalla 19.1

1. Mitä tehdään ensiksi?

1. Olio-ohjelmointi 1.1

4. Olio-ohjelmoinista lyhyesti 4.1

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

Olio-ohjelmointi 2. välikoe HYV5SN

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

Luento 4 Aliohjelmien toteutus

Rajapinnat ja olioiden välittäminen

Ohjelman virheet ja poikkeusten käsittely

812336A C++ -kielen perusteet,

Kääntäjän virheilmoituksia

Mikä yhteyssuhde on?

Tapahtumapohjainen ohjelmointi. Juha Järvensivu 2007

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu:

Sisällys. 19. Olio-ohjelmointia Javalla. Yleistä. Olioiden esittely ja alustus

Tässä dokumentissa kuvataan Keimo-projektissa sovellettavia ohjelmointikäytäntöjä. Päivämäärä Projektiryhmä Keimo

Virtuaalifunktiot ja polymorfismi

Java-kielen perusteet

Taulukot. Jukka Harju, Jukka Juslin

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

14. oppitunti. Operaattorin ylikuormitus. Osa. Operaattorin ylikuormittaminen

Graafisen käyttöliittymän ohjelmointi Syksy 2013

811120P Diskreetit rakenteet

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. V Geneerisyys

TIE Tietorakenteet ja algoritmit 25

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

Jakso 4 Aliohjelmien toteutus

Olio-ohjelmointi Geneerisyys. 1. Johdanto

TIETORAKENTEET JA ALGORITMIT

TIE Ohjelmistojen suunnittelu

Graafisen käyttöliittymän ohjelmointi

T Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

TIEA341 Funktio-ohjelmointi 1, kevät 2008

2. Olio-ohjelmoinista lyhyesti 2.1

Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet. TIES341 Funktio-ohjelmointi 2 Kevät 2006

Mallit standardi mallikirjasto parametroitu tyyppi

812341A Olio-ohjelmointi, IX Olioiden välisistä yhteyksistä

Ohjelmoinnin peruskurssien laaja oppimäärä

7/20: Paketti kasassa ensimmäistä kertaa

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Ohjelmoinnin peruskurssien laaja oppimäärä

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance)

Java-kielen perusteet

Osoittimet ja taulukot

Listarakenne (ArrayList-luokka)

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen

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

Transkriptio:

TIE-20200 Ohjelmistojen suunnittelu Luento 12 : Lambdat sun muut TIE-20200 Samuel Lahtinen Matti Rintala 1

Ohjelmassa tänään Lambdat, templatet, genericsit Erilaisia tapoja nähdä ohjelman rakenne: Single page application Entity component system Funktionaaliset jutut

Entity Component -juttu Ohjelman rakenne System-osassa ohjelman toiminnallisuusosat Esim. pelissä pelilogiikka, grafiikan piirto, fysiikkamoottori, törmäystarkastukset jne. Entity: yleiskäyttöinen objekti/olio/käsite, tunniste pelissä oleville asioille (sisältää tunnisteen, esim. int) Component: Tiedot jollekin tietylle käsitteelle yhdestä systemnäkökulmasta, data (joissain tapauksissa tarvittava toiminnallisuus) System-osien välillä tiedotusta esim. tapahtumien avulla Yleisin käyttökohde pelit (myös valmiit pelimoottorit/peli/ohjelmistokehykset (frameworkit)) No miksi tätä opetetettu heti kurssin alussa?

Entity Component juttuun liittyen Esimerkkejä ECS-lähestymistapaan liittyen: http://www.gamedev.net/page/resources/_/technical/game-programming/understandingcomponent-entity-systems-r3013 http://gameprogrammingpatterns.com/component.html http://www.richardlord.net/blog/what-is-an-entity-framework

Erittäin kevyesti funktionaalisista kielistä ~Kaikki esitetään funktioina, niiden parametreina & paluuarvoina Jotain funktionaalisuuteen liittyviä piirteitä: Sivuvaikutuksettomuus: funktion tulos aina sama samoilla parametreilla kutsuttuna Funktiot parametreina, paluuarvoina, korkeamman luokan funktiot Rekursion käyttö (ei silmukkamuuttujaa) Immutable data yleistä: tieto luonnin jälkeen muuttumatonta Epäpuhtauksia: tilamuuttujia, sivuvaikutusten salliminen (käyttöliittymään liittyvät asiat, tietojen syöttö/tulostus) Funktionaalisuuden tunkeutuminen normikielien (imperatiivisten) puolelle, esim. funktiot parametreina, lambdat, yms. rakenteet

Erittäin kevyesti funktionaalisista kielistä Johdantoa funktionaalisuuteen, Lambdat jne. Kannattaa tutustua johonkin funktionaaliseen kieleen: Yleissivistyksen kannalta hyvä Hyvä ajatustapaharjoitus Trendikästä teollisuudessa Pääsee eksklusiivisen kerhon jäseneksi ja voi päteä sanoilla kuten monadi, s-expression, atoms, catamorphism, puhdas funktio, higher order function, currying Helpompi hämätä asiakkaita jne., osa ymmärtää jo tavallisen koodin päälle Työkalut ja menetelmät osin epäkypsiä

Funktionaalisuudesta Kieliä: Haskell, Clojure, Lisp(Scheme) olio-funktionaalinen hybridit: Scala, F#, kummalliset: Erlang Lisäluettavaa kiinnostuneille Kurssimateriaalit: http://www.cs.tut.fi/~bitti/functional-seminar/ http://www.cs.tut.fi/~okp/2011/luentomatsku-pdf/funktio.pdf http://www.cs.helsinki.fi/u/mnykanen/fop/ http://www.mit.jyu.fi/opiskelu/seminaarit/bak/funktion/ http://www.cs.hut.fi/~cessu/fp-sem/ Online tutoriaaleja: http://tryhaskell.org/ http://www.tryclj.com/ http://java.ociweb.com/mark/clojure/article.html

Lambdat, C++11: miksi? Tarve välittää kirjastolle/funktiolle toiminnallisuutta callback-funktiot Geneeristen kirjastojen räätälöinti STL:n algoritmit (esim. find, sort) Koodin rinnakkainen suoritus Aiemmin sama mahdollista funktio-osoittimilla ja funktio-olioilla Kömpelömpiä, määrittely käyttökohteesta irrallaan

Funktio-osoittimista Funktio-osoittimet funktionaalisten kielten tyylisiä Parametrit ainoa data sisään, viiteparametrit & paluuarvo datana ulos bool alle5( int a ) return a < 5; std::find_if( v.begin(), v.end(), &alle5 ); Muun datan välitys vaikeaa (lähinnä globaalit muuttujat) int raja; // Oltava globaali muuttuja! bool allerajan( int a ) return a < raja; std::cin >> raja; std::find_if( v.begin(), v.end(), &allerajan );

Lambdat Lambdat ikivanha keksintö (Lisp) C++11:n lambdoissa kuitenkin joitain eroja Idea: Lambdat ovat funktion kaltaisia tuotteita, ottavat parametreja, palauttavat paluuarvon nimettömiä, määrittelemättömän tyyppisiä (melkein) pystyvät viittaamaan luontiympäristönsä muuttujiin, samoin muuttamaan pystyvät kopioimaan itseensä osia luontiympäristöstään

Lambdojen syntaksi []() C++11:n syntaksi lambdalle [ympäristö](parametrit)->paluutyyppirunko; Ympäristö tyhjä, jos ei viittaa ympäristöönsä parametrit tyhjä, jos ei parametreja (myös () sulut voivat puuttua) jos ->paluutyyppi puuttuu, se on void, paitsi jos runko pelkkä return-lause, jolloin päätellään

Lambda-esimerkkejä Lambda (std::sort-funktion parametriksi) std::sort( stuff.begin(), stuff.end(), // Lambda alkaa [](float a, float b) return (std::abs(a) < std::abs(b)); // lambda loppuu ); std::find_if( v.begin(), v.end(),[]( int a ) ->bool return a<5; ); std::find_if( v.begin(), v.end(),[]( int a )return a<5; ); int raja; // Paikallinen muuttuja std::cin >> raja; std:find_if( v.begin(), v.end(), [raja]( int a )return a<raja; );

Ympäristöön viittaaminen Lambda voi viitata paikallisiin muuttujiin: lambdan elinaika vs muuttujan elinaika! C++:n ongelma, muuttujilla määrätty elinaika (C++:n muistimalli) Toinen tapa ajatella: lambda saa parametreja ympäristöstään luontihetkellä, normaalit parametrit kutsuhetkellä Kaksi tapaa: arvon ja viitteen välitys

Ympäristön kopioiminen Tapa 1: ympäristön kopioiminen = (oletus) Käytetyt muuttujat kopioidaan lambdan sisään (vrt. arvoparametri), elinkaaret eivät ongelma Kopioita voi muuttaa vain, jos lambda on mutable int raja; std::cin >> raja; std::find_if( v.begin(), v.end(), [=raja](int a)return a<raja; ); std::for_each(v.begin(), v.end(), [raja](int a) mutable std::cout << ++raja; );

Ympäristöön viiteviittaaminen Tapa 2: Ympäristöön viittaaminen & Lambda käyttää suoraan ympäristön muuttujia Ohjelmoija vastaa, että muuttujat pysyvät elossa int summa = 0; std::for_each(v.begin(), v.end(),[&summa](int a)summa += a;);

Ympäristöön viittaaminen Ympäristöön viittauksia voi yhdistellä int raja = 5; int vertailuja = 0; std::find_if( v.begin(), v.end(), [=raja,&vertailuja](int a)->bool ++vertailuja; return a<raja; ); Implisiittinen ympäristöön viittaus (valittava, onko viite vai kopio) int raja = 5; int summa = 0; std::find_if( v.begin(), v.end(), [=](int a)return a<raja; ); std::for_each( v.begin(), v.end(), [&](int a)summa+=a; );

Ympäristöön viittaaminen, luokissa [this]() jäsenfunktiossa määritelty lambda voi viitata jäsenmuuttujiin ja -funktioihin class X int i_; void g( int x ); void f( std::vector<int> const& v ) std::for_each( v.begin(), v.end(), [this](int a) i_+= a; g(a); ); ;

Funktioon viittaus Fibonaccin sarjaa, esimerkkinä funktion antaminen ympäristönä std::function<int(int)> recursivefibonacci = [&recursivefibonacci]( int n ) return n < 2? 1 : recursivefibonacci( n-1 ) + recursivefibonacci( n-2 ); ;

Auton käyttöä, paikallinen funktio lambdalla Labdan kutsu määrittelyn jälkeen ei onnistu, ei nimeä, ei mitä kutsua C++11 sallii lambdojen tallentamisen myös nimettyihin muuttujiin voidaan kutsua samaa lambdaa useampaan kertaan int kerronta( std::vector<int>& v, std::list<int>& l ) int x=1; auto kerro = [&](int i)x *= i;; // lambda talteen for( auto i: v ) kerro( i ); // käyttö vektorilla for( auto i: l ) kerro( i ); // käyttö listalla return x;

Lambdan toteutus? Yksi mahdollisuus: lambdat funktio-olioita Nimettömiä luokkia, joissa kutsuoperaattori operator() Jäsenmuuttuja jokaista ympäristöviittausta kohti (viite, jos viittaus ympäristöön) Kääntäjä saa myös toteuttaa miten haluaa Esim. funktio-olio, jossa suoraan aktivaatiotietueen osoite yms.

C# lambdat sun muut Tukee lambdoja, myös LINQ (Language- Integrated Query) Käyttö kuten C++:ssa, public partial class Form1 : Form customers.where(c => c.city == "London"); public Form1() InitializeComponent(); button1.click += async (sender, e) => // ExampleMethodAsync returns a Task. await ExampleMethodAsync(); textbox1.text += "\r\ncontrol returned to Click event handler.\r\n"; ; async Task ExampleMethodAsync() // The following line simulates a task-returning asynchronous process. await Task.Delay(1000); TIE-20200 Samuel Lahtinen http://msdn.microsoft.com/en-us/library/bb397687.aspx

C# LINQ-esimerkki class LINQQueryExpressions static void Main() // Specify the data source. int[] scores = new int[] 97, 92, 81, 60 ; // Define the query expression. IEnumerable<int> scorequery = from score in scores where score > 80 select score; // Execute the query. foreach (int i in scorequery) Console.Write(i + " "); // Output: 97 92 81 http://msdn.microsoft.com/en-us/library/bb397933.aspx

Java & Lambdat (Java 8) Java 8:ssa tukea lambdoille (hieman rajatumpi kuin c++/c#) Arrays.sort(words, (first, second) -> Integer.compare(first.length(), second.length())); public static void repeatmessage(string text, int count) Runnable r = () -> for (int i = 0; i < count; i++) System.out.println(text); Thread.yield(); ; new Thread(r).start();

Geneerisyys ja mallit (mallineet, sapluunat ) (generics & templates) Perintä ja polymorfismi: kantaluokkaosoittimen/viittee Esim. funktiolle kelpaa mikä tahansa kantaluokan tyy Periytymissuhdevaatimus ei aina hyvä asia Mallin idea: Koodissa yksi tai useampi auki jätetty tyyppiparametri auki jätetty tyyppi kiinnittämällä saadaan todellista koodia Malli on mahdollista instantioida useita kertoja useita sam TIE-20200 Samuel Lahtinen 24

Aihiot, mallineet Mallit mahdollistavat geneerisen ohjelmoinnin (gener Auki jätetyn tyypin käyttö koodissa määrää sen omina Sijoitus sijoitusoperaattori oltava Arvoparametrina kopiorakentaja oltava Jäsenfunktiokutsu ko. jäsenfunktio löydyttävä Mallia käytettäessä ominaisuusvaatimukset eivät tote Mallia suunniteltaessa hyvä minimoida ominaisuusva TIE-20200 Samuel Lahtinen 25

Funktiomallit (function template) Malli funktioille, joissa tyyppejä (normaalisti parametreja) jätetty auki Listaus 9.5 s. 233 (9.5 s. 259): 1 template<typename T> // Tai template <class T> (identtinen) 2 T min(t p1, T p2) 3 4 T tulos; 5 if(p1 < p2) 6 7 tulos = p1; 8 else 9 tulos = p2; 10 11 return tulos; 12 Funktiomalli instantioidaan automaattisesti kutsuttaessa (mahdollista myös kertoa tyyppi ekp min(1,2) int min(int p1, int p2) min( a, e ) char min(char p1, char p2) TIE-20200 Samuel Lahtinen 26

Luokkamallit (class template) Malli luokille, joissa tyyppejä jätetty auki Itse malli ei ole luokka, vaan siitä tehdyt instanssit Luokkamallit instantioitava aina ekplisiittisesti: Jokainen instanssi oma tyyppinsä, jotka eivät ole keskenää TIE-20200 Samuel Lahtinen 27

Luokkamalli-esimerkki // hieno luokkamalli, joka laskee minkä tahansa olioiden/muuttujien // instanssien määrän template< typename T > class Laskuri public: Laskuri(): laskuri_() ~Laskuri() void lisaa( T stat ); void tulosta( std::ostream& out ) const; T annayleisin() const; private: typedef map< T, long > IRegister; typedef typename IRegister::const_iterator citerator; IRegister laskuri_; ; TIE-20200 Samuel Lahtinen 28

Luokkamallin toteutukset template< typename T > void Laskuri< T >::lisaa( T stat ) laskuri_[ stat ]++; template< typename T > void Laskuri< T >::tulosta( std::ostream& out ) const out << "kutakin tyyppiä oli (tyyppi - määrä): " << endl; for( citerator it = laskuri_.begin(); it!= laskuri_.end(); ++ it ) out << "'" << it->first << "' - " << it->second << endl; template< typename T > T Laskuri< T >::annayleisin() const if( laskuri_.empty() ) throw std::out_of_range( "Laskuri on tyhjä" ); citerator yleisin = laskuri_.begin(); for( citerator it = laskuri_.begin(); it!= laskuri_.end(); ++ it ) if( yleisin->second < it->second ) yleisin = it; return yleisin->first; TIE-20200 Samuel Lahtinen 29

Luokkamallin käyttö int main() Laskuri< char > chars; cout << "kirjoittele jotain ja paina enter..." << endl; string temp; std::getline( std::cin, temp ); if( std::cin.eof() )std::cout<< "EOF!!!!" << endl; for( unsigned i( 0 ); i < temp.size(); ++i ) chars.lisaa( temp.at( i ) ); chars.tulosta( cout ); cout << "yleisin merkki oli: " << chars.annayleisin() << endl; cout << "Sama murtoluvuilla" << endl; Murtoluku m1( 5,6); Murtoluku m2( 5,6); Murtoluku m3( 5,9); Murtoluku m4( 1,6); Murtoluku m5( 5,9); Murtoluku m6( 5,12); Murtoluku m7( 5,6); Murtoluku m8( 2,3); Laskuri< Murtoluku > murtoluvut; murtoluvut.lisaa( m1 ); murtoluvut.lisaa( m2 ); murtoluvut.lisaa( m4 ); murtoluvut.lisaa( m5 ); murtoluvut.lisaa( m6 ); murtoluvut.lisaa( m7 ); murtoluvut.lisaa( m8 ); murtoluvut.tulosta( cout ); TIE-20200 Samuel Lahtinen 30

Tyyppiparametrien vaatimukset Mitä ominaisuuksia mallin tyyppiparametrilla pitää olla Malli ei kerro sitä eksplisiittisesti Ainoa vaatimus: mallin koodin on käännyttävä Ongelma: koodin vaatimukset vaikeasti näkyvissä Ohjeita geneeriseen ohjelmointiin: Tyyppiparametrien vaatimukset dokumentoitava selkeästi Vaatimusten määrä minimoitava yleiskäyttöisyyden lisäämis Tiedettävä kääntäjän kulissien takana tekemän koodin vaa TIE-20200 Samuel Lahtinen 31

Yhteenveto Opittiin, että isot perintähierarkiat ja sun muut eivät aina ole oikea tapa lähestyä asioita Saatiin pakollinen mainosspämmi funktionaalisista kielistä Lambdat, funktionaalista ohjelmointia ei-funktionaalisella kielellä? (Mitä eroja puhtaaseen funktionaalisuuteen?) Opittiin lambdojen perusidea ja käyttö Kertauksena templatet, muistuksena yleiskäyttöisyydestä ja sen hyödyistä/vaaroista