Az arrow struktúra. Patai Gergely április 1.

Méret: px
Mutatás kezdődik a ... oldaltól:

Download "Az arrow struktúra. Patai Gergely április 1."

Átírás

1 Az arrow struktúra Patai Gergely április Kiinduló motiváció A funkcionális nyelvek alapvető építőeleme a függvény. Egyszerű függvényekből különböző kombinátorok segítségével bonyolultabb függvények építhetők fel anélkül, hogy expliciten meg kellene említeni az általuk feldolgozott adatokat. A point-free style olyan programozási stílus, amely ezt a megközelítést emeli ki. A point szó a topológia területéről származik, és az adatokra utal, amelyek között a függvények (vagy általánosabban morfizmusok) átjárást biztosítanak. A gyakorlatban arról van szó, hogy a függvényeket próbáljuk úgy definiálni, hogy az argumentumok implicitek legyenek. A legalapvetőbb kombinátor a függvénykompozíció. Például definiáljunk egy függvényt, amely megszámolja egy sztringben egy adott szó előfordulásait: countw1 w s = length (filter ( w) (words s)) Kompozíció használatával ez a művelet sokkal intuitívabban fejezhető ki, mivel a fenti definíció alapján jól láthatóan egymás után következő fázisokra bontható: countw2 w s = (length filter ( w) words) s Az s argumentumot implicitté téve ezzel ekvivalens definíciót kapunk: countw3 w = length filter ( w) words Ez persze még nem teljesen point-free, hiszen a számlálandó szó továbbra is megjelenik a definícióban. Ezen is lehet változtatni 1, viszont az így kapott kifejezés már sokkal nehezebben értelmezhető: countw4 = (length ) ( words) filter ( ) Egyértelmű, hogy az első transzformáció javítja az olvashatóságot, a második viszont nagy mértékben rontja. Ez nem feltétlenül a megközelítés hibája, sokkal inkább a függvénykompozíció kifejezőkészségének a korlátja ebben a konkrét esetben az a baj, hogy a w argumentumot egy műveletsor közepére kell bejuttatni. Okosabb kombinátorok használatával könnyen elképzelhető valami más, jobban olvasható definíció. Más probléma is akad. Tegyük fel, hogy a függvényünket perifériákon szeretnénk értelmezni, azaz a szöveget file-ból venni és az eredményt kiírni: countwio w = print length filter ( w) words readfile Csakhogy ezt nem engedi meg a Haskell típusellenőrzője! Az a baj, hogy a readfile és a print is mellékhatással jár, és a típusukban megtalálható az IO monád: readfile :: String IO String print :: Show a a IO () Természetesen ez a típusellenőrzés előnye, hiszen így meg tudjuk különböztetni a tiszta függvényeket a mellékhatásosoktól. A baj az (ahogy már a monádoknál is láthattuk), hogy az ilyen függvények közvetlenül nem komponálhatók a többivel. A közvetlen megoldás egyszerű, csak az adott monád bind ( >=) műveletét kell segítségül hívni és a tiszta műveleteket monadikussá alakítani: countwio1 w = ( >=print) liftm (length filter ( w) words) readfile Ez azonban megint nehezebben olvasható, mint az eredeti változat. Az arrow struktúra olyan tervezési minta, amely a fent említett problémákra elegáns megoldást ad. 1 Thomas Jäger pointfree programjának segítségével 1

2 2. A kompozíció általánosítása Először a monádok és a függvények egységesítésével foglalkozunk. Mint emlékszünk, a monadikus függvények típusa α µ β. Ahhoz, hogy ezzel kényelmesen dolgozhassunk, érdemes egy típusszinonimát deklarálni: type Kleisli m a b = a m b Ezután a readfile és a print típusát a következő módon is leírhatjuk: readfile :: Kleisli IO String String print :: Show a Kleisli IO a () A Kleisli név a kategóriaelméletből ered, amivel itt nem foglalkozunk. A lényeg, hogy ez a típus tetszőleges monádot takarhat. Mivel ez a típus leképzést jelöl (ellentétben a monáddal, amely csak egy statikus absztrakciónak felel meg), így tulajdonképpen ez már egy Kleisli arrow. Ha van két ilyen függvényünk egy α-ból β-ba, valamint egy β-ból γ-ba, akkor a kompozíciójuk egy α-ból γ-ba képző arrow-t ad, amely a mellékhatásaikat is sorbarendezi. A következőkben ezt a műveletet definiáljuk. A függvénykompozícióhoz képest fordított sorrendben vesszük az argumentumokat, hogy a jelölésünkben az arrow-k sorrendje megfeleljen a mellékhatásaik sorrendjének: ( >) :: Monad m Kleisli m a b Kleisli m b c Kleisli m a c (f > g) a = do b f a g b Az így kapott kompozíciós operátort felhasználva már a mellékhatásos függvények esetén is könnyen visszatérhetünk a point-free jelölésre: printfile = readfile > print Viszont az eredeti példánkat még nem fejezhetjük ki ezzel az operátorral, mert mellékhatásmentes függvényeket is tartalmaz a kompozíció, amelyeknek pont ezért nem megfelelő a típusa. Szerencsére ezek a függvények könnyen mellékhatás nélküli Kleisli arrow-vá alakíthatók egy újabb kombinátorral: arr :: Monad m (a b) Kleisli m a b arr f = return f Ezt felhasználva már felírható a függvény új alakja: countwio2 w = readfile > arr words > arr (filter ( w)) > arr length > print 3. Az Arrow osztály Mivel már kétféle point-free jelölésünk van (egy függvényekre és egy arrow-kra épülő), érdemes ezeket közös nevezőre hozni. A Haskell típusosztályai erre jól használható eszközt nyújtanak, mivel a segítségükkel lehetőség nyílik az arrow operátorok túlterhelésére. Első lépésként definiáljuk az ehhez szükséges osztályt: class Arrow arr where arr :: (a b) arr a b ( >) :: arr a b arr b c arr a c Ennek az osztálynak az egyik példánya a közönséges függvények típusa: instance Arrow ( ) where arr = id ( >) = flip ( ) 2

3 Ha a tiszta függvények körében maradunk, akkor ez csupán egy alternatív jelölés a kompozícióra. Ahhoz, hogy a Kleisli arrow-kat is példánnyá tegyük, típusszinonima helyett új típusként kell őket deklarálni, hogy kapjunk egy típuskonstruktort: newtype Kleisli m a b = Kleisli{runKleisli :: a m b } instance Monad m Arrow (Kleisli m) where arr f = Kleisli $ return f Kleisli f > Kleisli g = Kleisli $ ( >=g) f Ha ez megvan, felírhatjuk a szószámláló függvény újabb definícióját: countwio3 w = Kleisli readfile > arr words > arr (filter ( w)) > arr length > Kleisli print Ennek futtatása a következőképpen történik: runkleisli (countwio3 w) filename Láthatóan az új konstruktor kicsit felhígítja a jelölést, de legalább lehetővé teszi, hogy a monádokat és a függvényeket immár egyformán kezeljük egy absztrakciós lépést (az arr illetve Kleisli csomagoló műveleteket) követően. Ezt a jelölést bármely Haskell programban használhatjuk a Control.Arrow könyvtár importálása után, amely többek között az Arrow és a Kleisli definícióját is tartalmazza. 4. Az arrow értelmezése Eddig kétféle példányosítását ismertük meg az arrow mintának, de mielőtt újabbakat keresnénk, érdemes belegondolni, mit is várunk általánosságban ettől a struktúrától. A monádok bevezetésekor a kiindulópont az volt, hogy az absztrakciók mögé rejtett adatok helyes kezelését akartuk kikényszeríteni. Ennek megfelelően a monádot egyfajta csomagként fekete dobozként tekinthetjük, amelyről csak azt tudjuk, hogy milyen típusú adatot tartalmaz. Az adott csomagtípushoz tartozó return és >= műveletek lehetővé teszik, hogy a csomag megbontása és szerkezetének ismerete nélkül dolgozhassunk a benne tárolt adatokkal. Láttuk, hogy ez a két művelet elég is minden monádhoz (emellett természetesen több monádtípus még definiál pluszban specifikus műveleteket, pl. az állapotmonád esetén az állapot explicit kezelésére szolgáló get és set függvényeket). A csomag persze akár mellékhatásos számítás is lehet, ekkor az említett műveletek biztosítják a mellékhatások helyes menedzselését. Ezzel szemben az arrow általánosságban olyan folyamatnak tekinthető, amelyet a be- és kimenetének típusa jellemez. Azaz míg a monád valamilyen adatot rejt absztrakció mögé, addig az arrow egy transzformációt. Ez látszik is a konstruktorukon, hiszen a return tetszőleges típust elfogad, az arr viszont kötelezően függvényt vár. Természetesen a monádba is csomagolhatunk függvényt, mert a funkcionális programozás alapelve szerint az is csak adat, de lényeges különbség, hogy maga a monád nem tud különbséget tenni konstansok és függvények között, míg az arrow eleve arra épít, hogy a becsomagolt adat függvény, így alkalmazható a megfelelő típusú argumentumra. Tehát a monádba csomagolt függvény passzív marad, míg az arrow egyfajta keretrendszert biztosít a futtatásához. 5. Az egységesítés haszna Sem a monádok, sem az arrow-k nem kapcsolódnak szorosan egy alkalmazásukhoz sem. A monádok például sokszor előjönnek, ha imperatív nyelvek viselkedését szeretnénk modellezni, de ettől függetlenül használhatók funkcionálisan tiszta kód strukturálására is. Végeredményben a monádstruktúra (és az arrow is) olyan interfészt definiál, amelyet nagyon sokféle kombinátorkönyvtár képes implementálni. A közös interfész mindenképpen előnyös: sok olyan hasznos művelet van, amely a közös monádműveleteken alapszik; ezeket mind ingyen megkapjuk, ha a könyvtárunkat monádként definiáljuk 3

4 transzformerek használatával szisztematikusan kombinálhatunk különböző könyvtárakat, ezzel pedig nagyon sok munka takarítható meg ha egy interfész ennyire általánosan használható, akár közvetlen nyelvi támogatás adható rá (a Haskell esetében például a do-szintaktika); ez szépen beleillik abba az általános tendenciába, hogy a különböző tervezési minták egy nemzedékkel később nyelvi primitívként jelennek meg a könyvtárakat használó programozónak is egyszerűbb a dolga, hiszen ismerős műveletekkel dolgozik 6. A teljes Arrow osztály Van egy hatalmas különbség a monádok és az arrow-k interfésze között, amely nagyban befolyásolja ezeknek a mintáknak az alkalmazási módját. Vessünk egy pillantást a kompozíciós operátoraik típusára: ( >=) :: m a (a m b) m b ( >) :: a b c a c d a b d A monádok esetén a >= második argumentuma Haskell függvény, így a nyelv teljes kifejezőereje rendelkezésünkre áll, hogy a bejövő csomagból előállítsuk a kimenő csomagot. Mikor két monádszámítást sorbaállítunk, közöttük tetszőleges Haskell kódot futtathatunk. Ezzel szemben az arrow-k esetén a > második argumentuma szintén arrow, azaz absztrakt adattípus, így csak olyan műveleteket végezhetünk rajta, amelyet az ahhoz tartozó interfész definiál. Ugyan az arr művelettel beemelhetünk egy függvényt az absztrakció mögé, viszont ez csak tiszta függvény lehet az arrow szempontjából, tehát az egyéb hatásai nem érvényesülhetnek. Ha azt szeretnénk, hogy a második arrow hatásai az első hatásaitól függjenek, akkor az arr és > mellett valami újabb műveletet is be kell vezetnünk. Tegyük fel, hogy szeretnénk két egész számot visszaadó számítást egymás után lefuttatni, majd az eredményeiket összeadni. Monádokkal ez nagyon egyszerű: addm :: (Num a,monad m) m a m a m a addm ma mb = do x ma y mb return (x + y) De az eddig látott arrow interfész még ezt sem képes kifejezni! Ha viszont lenne egy olyan műveletünk, amely képes párba állítani két arrow (f és g) kimenetét, akkor ezt a párt már át lehetne adni az arr (uncurry (+)) kifejezéssel felépített arrow-nak. Ezt viszont nem definiálhatjuk a már ismert műveletekkel, mert az >f > alakú kompozíció értelemszerűen eldob mindent f kimenetén kívül. A megoldás egy új operátor bevezetése: ( &) :: a b c a b d a b (c,d) Visszatérve a Haskell megvalósításra az osztály és a két már ismert példány definíciója így bővül: class Arrow arr where ( &) :: arr a b arr a c arr a (b,c) instance Arrow ( ) where (f & g) a = (f a,g a) instance Monad m Arrow (Kleisli m) where Kleisli f & Kleisli g = Kleisli $ λa do b f a c g a return (b,c) Ennek segítségével már definiálható az adda: adda :: (Arrow arr,num c) arr a c arr a c arr a c adda f g = f & g > arr (uncurry (+)) 4

5 Ugyan a & operátor kényelmesen használható, de sajnos elég bonyolult is. Figyelembe kell venni, hogy az arrow-k gyakorlati használatához sok műveletet kell bevezetnünk, és ezeket nehézkes egyenként implementálni. Mivel a Haskell lehetővé teszi alapértelmezett kód futtatását, célszerű olyan egyszerű operátorokat keresni, amelyekből a többi kifejezhető. A & többek között megduplázza a bemenetét, hogy mindkét argumentumának átadhassa. Mivel a duplázás arrow-sított tiszta függvénnyel megoldható (arr (λx (x, x))), ezért ezt a funkciót kivehetjük, és &-t kifejezhetjük az egyszerűbb segítségével, amely két arrow-t párhuzamosít úgy, hogy a be- és kimeneteiket párba állítja: ( ) :: a b c a d e a (b,d) (c,e) Azaz a Haskell definícióban: class Arrow arr where ( ) :: arr a b arr c d arr (a,c) (b,d) f & g = arr (λx (x,x)) > f g De ne is foglalkozzunk a közvetlen megvalósításával, mert van egyszerűbb kombinátor is, amellyel kifejezhető. A két arrow-ból csinál egy párokon működő arrow-t, ami visszavezethető arra a speciális esetre, ahol az egyik az azonosság, amely mellékhatás nélkül továbbadja a bemenetét. Vezessük be tehát a first műveletet, amely egy tetszőleges arrow-t párbaállít az azonossággal: class Arrow arr where first :: arr a b arr (a,c) (b,c) instance Arrow ( ) where first f (a,c) = (f a,c) instance Monad m Arrow (Kleisli m) where first (Kleisli f ) = Kleisli $ λ(a,c) do b f a return (b,c) Ha a operátort vettük volna primitívnek, akkor a first definíciója a következő lehetett volna: first f = f arr id Ehelyett a first-re építkezünk. Először definiáljuk a párját second néven, amely a pár második tagját vezeti át az arrow-n: class Arrow arr where second :: arr a b arr (c,a) (c,b) second f = arr swap > first f > arr swap where swap (x,y) = (y,x) Ezután a megadható alapértelmezett műveletként: class Arrow arr where f g = first f > second g Ez a definíció egyben azt is tisztázza, hogy az f mellékhatásai megelőzik a g-éit. Természetesen tetszőleges mennyiségű hasonló operátort lehetne definiálni, azonban ezek alapvetően mind kifejezhetők az arr, > és a first segítségével, valamint tiszta műveletek (pl. a & esetén a bemenet megduplázása) felhasználásával. Az itt bemutatott operátorok vizuális értelmezését az 1. ábra mutatja. A Control.Arrow könyvtárban található Arrow osztály tartalmazza ezeket az operátorokat az említett alapértelmezett megvalósítással, így új arrow példányosításakor elég az arr, > és first függvényeket megírni. Hatékonysági okokból általában a többit is célszerű közvetlenül implementálni a későbbiekben, de ahhoz nem kellenek, hogy az új adatstruktúránkat működésre bírjuk. 5

6 arr f f > g first f f f g f second f f f g f g f & g f g 7. Visszacsatolás 1. ábra. Az arrow-kombinátorok Ha az arrow-kat adatfolyamgráfok építőelemeinek tekintjük, adja magát a kérdés, hogy hogyan lehetne köröket alkotni, hiszen a funkcionális világban természetes a rekurzió használata. Az itt definiált kombinátorok ezt nem teszik lehetővé, ezért be kell vezetnünk egy újabbat. Ez azonban már plusz szolgáltatást jelent az alapfunkciókon felül, így semmi esetre sem bővíthetjük az új kombinátorral az Arrow osztályt. Ehelyett egy alosztályt kell definiálni, amely egy új elemmel egészíti ki az interfészt: class Arrow arr ArrowLoop arr where loop :: arr (a,c) (b,c) arr a b A loop kombinátor egy arrow második kimenetét a második bemenetére csatolja vissza. A közönséges függvények esetén ez rekurzív definícióhoz vezet: instance ArrowLoop ( ) where loop f a = let (b,c) = f (a,c) in b A furcsán ható definíció gyakorlatilag arra jó, hogy kiváltsa a rekurziót a függvény fixpontjának kiszámításával. Például a szokásos faktoriális a következő függvény fixpontjaként adódik: facloop (x,f ) = (f x,fn) where fn 0 = 1 fn n = n f (n 1) Használatára példa: loop facloop 7 Könnyen ellenőrizhető, hogy ez a kifejezés tényleg 5040-re redukálható. Ami a másik példányt illeti, csak a MonadFix osztályba tartozó monádokon értelmezett Kleisli-arrow struktúrák esetén implementálható loop, amivel most nem foglalkozunk. 8. Adatfolyamok Bár az ArrowLoop bevezetése jó ötletnek látszik, sem a függvények, sem a monádok esetén nincs igazi haszna, hiszen csak egy alternatív, a szokásosnál bonyolultabb módot ad a rekurzió leírására. A valódi adatfolyamok esetén viszont tényleg van értelme a hurkoknak, így érdemes megvizsgálni, hogy alkalmas-e az arrow struktúra ezek leírására. Legyen a kiindulópont a folyamokon értelmezett függvény, ahol a folyamokat listákkal modellezzük: newtype SF a b = SF {runsf :: [a] [b]} Ezután hozzuk létre az ilyen függvényeken értelmezett arrow példányt: 6

7 instance Arrow SF where arr f = SF $ map f SF f > SF g = SF $ f > g first (SF f ) = SF $ unzip > first f > uncurry zip Az implementációban kihasználjuk azt, hogy a tiszta függvények is arrow-k, így jól olvasható egységes jelölést kapunk. Ezután megpróbálkozhatunk a loop-pal is: instance ArrowLoop SF where loop (SF f ) = SF $ λas let (bs,cs) = unzip (f (zip as cs)) in bs Ezzel azonban gond van: ha például vesszük a loop (arr id) kifejezéssel felépített arrow-t, akkor azt várnánk, hogy úgy viselkedjen, mint a sima azonosság. A probléma gyökere az, hogy mind a zip, mind az unzip szigorú kiértékelésű, azaz muszáj kiértékelniük az argumentumaikat, mielőtt bármit is visszaadhatnának. Emiatt a rekurzió holtponthoz vezet. A megoldás a lusta minták használata: instance ArrowLoop SF where loop (SF f ) = SF $ λas let (bs,cs) = unzip (f (zip as (stream cs))) in bs where stream (x : xs) = x : stream xs A lusta minta mindenképpen illeszkedik, viszont ha később kiderül, hogy az átadott struktúra nem megfelelő, akkor hiba keletkezik. Ebben az esetben ez nem történik meg, hanem keletkezik egy végtelen lista, amelynek az elemei nem definiáltak. A zip ezeket az elemeket olyan párokkal tölti ki, amelyeknek első tagja az as listából jön, a második pedig még mindig definiálatlan. Viszont a holtpontot feloldottuk, és a függvényekhez hasonló módon működik a loop új változata. Érdemes végiggondolni a runsf (loop (arr swap)) [1, 2, 3] kifejezés kiértékelésének menetét, amely a következő kifejezéssel ekvivalens: loopexample = bs where (bs,cs) = unzip (map swap (zip [1, 2, 3] (stream cs))) swap (x,y) = (y,x) stream (x : xs) = x : stream xs Ahhoz, hogy a hurok tényleg használható legyen, definiálni kell egy olyan műveletet, amely csak a folyamokon értelmezhető, a függvényeken és a monádokon nem: az egyszerű késleltetést. Ezzel olyan bővítményt kapunk, amellyel tetszőleges szinkron hálózatot le tudunk írni, így ehhez is érdemes egy szűkebb arrow-osztályt is definiálni: class ArrowLoop arr ArrowCircuit arr where delay :: a arr a a instance ArrowCircuit SF where delay x = SF (x:) A delay egy óraütéssel késlelteti a rajta átmenő adatforgalmat, az első értéket pedig az argumentumában megadott érték előzi meg a kimeneten. A hurokba helyezett késleltetésre a stabilitás miatt van szükség. Így pontosan tudjuk szabályozni, hogy a kimenet mely korábbi értékeit szeretnénk felhasználni a következő iterációban. Próbáljunk akkor az eddig definiált műveletekkel egy újabb faktoriálisfüggvényt írni! Az adatfolyamhálót a 2. ábra mutatja. Először kell egy szorzóelem, amelynek két bemenete és egy kimenete van: mul :: (Num n,arrow arr) arr (n,n) n mul = arr (uncurry ( )) Ha a kimenetének a másolatát visszacsatoljuk egy késleltetésen keresztül, akkor egy egyszerű akkumuláló struktúrát kapunk: 7

8 mulacc mul delay 1 2. ábra. Szorzó-akkumulátor struktúra mulacc1 :: (ArrowCircuit arr,num n) arr n n mulacc1 = loop (mul > (arr id & delay 1)) Ezt megfelelően felparaméterezve már meg is oldottuk a feladatot: fac1 :: (Num a,enum a) a a fac1 n = last $ runsf mulacc1 [1..n] 9. A do-szintaktika kibővítése Bár az arrow-kombinátorok viszonylagos gazdagsága miatt sokkal egyszerűbb velük a munka, mint a monádok egyetlen >= műveletével, nagyobb programokat nehézkes ilyen formában leírni. A monádoknál már látott megoldás itt is működik: a point-free megközelítést elvetjük, és újra explicitté tesszük az adatokat, azaz az egyes arrow-k be- és kimeneteit. Egy arrow-t a proc kulcsszóval vezetünk be, amelyet a bemenetre illeszkedő minta, majd egy jobbra mutató nyíl (, azaz egy kötőjel és egy kacsacsőr kombinációja: ->) követ. A nyíl másik végén egy arrow-kifejezésnek kell állnia. Ez a legegyszerűbb esetben az arr input alakot ölti, ahol arr maga a használt arrow, input pedig egy tiszta Haskell kifejezés, amelynek az eredményét szeretnénk az arrow bemenetére kötni. A is egy kötőjelet követő, de ellenkező irányú kacsacsőr: -<. A kimenet arr kimenete lesz, ezért nem kell explicit nevet kapnia. Például egy egyszerű összeadó definíciója lehetne a következő: adder = proc (x,y) arr id x + y Látható, hogy tiszta kifejezés nem állhat csupaszon, hanem be kell csomagolni az identitás-arrow felhasználásával. Ez analóg a monadikus return művelettel, ezért is definiálták a returna arrow-t: returna = arr id Természetesen általában több arrow-t szeretnénk kombinálni egy definícióban, így a köztes értékeket is meg kell jeleníteni a forrásban. Ez a monádokéhoz nagyon hasonló do-jelöléssel lehetséges. A különbség lényegében csak annyi, hogy a szokásos kicsomagoló nyilak ( ) jobb oldalán most monádok helyett arrow-k állnak, azaz arr input alakú kifejezések. Például próbáljuk definiálni a & kombinátort ezzel a szintaxissal! f & g = proc x do y1 f x y2 g x returna (y1,y2) Az operátorok nem véletlenül formálják egy nyíl fejét és farkát. Adja magát az interpretáció, hogy a jobb oldalon látható kifejezést a középen megadott arrow-n keresztülküldve a bal oldali értéket kapjuk. Csak azt kell észben tartani, hogy nem egyszerűen argumentumként adjuk át az értékeket, hanem a operátor (amely szintaktikai elem, nem infix jelölésű Haskell függvény!) felhasználásával. Ez azért van, mert az arrow-k általánosságban nem függvények, így nem függvényalkalmazásról van szó. Ezután már csak a hurkok leírása hiányzik. Mint említettük, a loop kombinátor gyakorlatilag a rekurzió átfogalmazása, így nincs is másról szó, mint az azonosítók kölcsönösen rekurzív deklarációjáról. Elvileg ennyi 8

9 reset if reset then 0 else next counter out next delay 0 out + 1 inc 3. ábra. Resetelhető számláló elég is lenne, viszont implementációs okokból az ilyen jellegű felhasználást a rec kulcsszóval kell jelezni, és az ilyen blokkokat célszerű csak azokra az arrow-kra korlátozni, amelyeknél tényleg szükség van erre. Az így kapott do-jelölést felhasználva az előbb látott faktoriális például a következő módon definiálható: mulacc2 :: (ArrowCircuit arr,num n) arr n n mulacc2 = proc x do rec prod mul (x,prec) prec delay 1 prod returna prod fac2 :: (Num a,enum a) a a fac2 n = last $ runsf mulacc2 [1..n] Vegyünk egy kicsit bonyolultabb példát. Hozzunk létre egy resetelhető számlálót, amelynek csak egy boolean bemenete van, a kimenete pedig egész számok folyama. A hálózatot a 3. ábra mutatja. counter1 :: ArrowCircuit a a Bool Int counter1 = proc reset do rec next delay 0 out + 1 out returna if reset then 0 else next returna out Például a következő módon tudjuk futtatni: runsf counter1 $ map ( r ) "...r.rrr...r...r." Próbáljuk most ugyanezt leírni az ismert kombinátorokkal: counter2 :: ArrowCircuit a a Bool Int counter2 = loop $ cond > returna & (inc > delay 0) where cond = arr (λ(reset,next) if reset then 0 else next) inc = arr (+1) Jól látható, hogy az átírás bonyolult, és semmi esetre sem oldható meg olyan egyszerű szabálygyűjteménnyel, ami a monádok do-szintaxisánál működik. Az például egyértelmű, hogy a jobb oldalon található tiszta kifejezéseket arrow-ba kell csomagolni, hogy beilleszthessük őket a struktúrába, de a különböző értékeket már egyáltalán nem egyszerű eljuttatni a megfelelő pontokba. Ebben az esetben azért is könnyű a dolgunk, mert nincs olyan kifejezés, amely kettőnél több paramétert vár, így a beágyazása egyszerűen leírható a már definiált kombinátorokkal. Ha mondjuk a számláló induló értékét is kívülről vennénk egy másik adatfolyamból, a cond komponensnek máris három bemenete lenne, amely újabb kombinátor híján csak egymásba ágyazott párokkal írható le. Ez természetesen még távolabb viszi egymástól a do-jelölést és a kombinátorost. Mindezt figyelembe véve megállapíthatjuk, hogy ez a transzformáció már összetett fordítási lépés, hacsak nem akarunk teljesen lemondani az optimális megvalósításról. A hatékonyság növeléséhez minél több kombinátort kéne bevezetni (pl. az említett hárombemenetű esetre), ám ezzel több probléma is van. A legkisebb gond az, hogy ezeket mind meg is kell valósítani az arrow definiálásakor, mert az alapértelmezett implementáció csak arra jó, hogy rossz hatékonysággal ugyan, de legalább működjön a program (ez ekvivalens azzal, hogy nem is bontjuk meg az absztrakciót). Az első nehéz kérdés inkább az, hogy milyen kombinátorokat is definiáljunk, hiszen a lehetséges struktúrák száma robbanásszerűen nő még kevés be- és kimenet esetén is. Ha ezt valahogy sikerült eldöntenünk, rögtön azzal szembesülünk, hogy a fordító nagyon gyorsan elbonyolódik, ha ezeket ki is akarjuk használni az átírásnál. Nem véletlen, hogy a jelenlegi preprocesszor csak az említett operátorokból dolgozik, és a végeredmény messze nem optimális. 9

10 10. További érdekes bővítések Feltételes kifejezések Alapötlet: feltételhez kötjük egy arrow létezését. Ehhez bevezetünk egy if-then-else kombinátort: ifte :: Arrow arr arr a Bool arr a b arr a b arr a b Azaz ifte p f g a p folyam aktuális értékétől függően f -ként vagy g-ként viselkedik. Viszont ez is visszavezethető egyszerűbb elemekre. Első lépés: p-t kiemeljük előre, hiszen mindenképpen ki kell értékelni f vagy g előtt. Bevezetünk helyette egy olyan kombinátort, amely az eredeti bemenetet és a p kimenetét várja: ifte p f g = p & arr id > f g A az első (boolean típusú) bemenetétől függően a másodig bemenetét vagy az f, vagy a g arrow-n keresztül küldi tovább. Ennél még jobb, ha egy (Bool,a) típusú bemenet helyett Either a b-t használunk, így az is lehetséges, hogy a két esetben két különböző típusú adatunk legyen. A szokásos módon származtatunk egy újabb típusosztályt: class Arrow arr ArrowChoice arr where ( ) :: arr a c arr b c arr (Either a b) c Erre azért is van szükség, mert nem feltétlenül tudja minden arrow-típus biztosítani ezt a műveletet. Például ezzel definiálhatjuk a MapA-t: mapa :: ArrowChoice arr arr a b arr [a] [b] mapa f = arr listcase > arr (const [ ]) (f mapa f > arr (uncurry (:))) where listcase [ ] = Left () listcase (x : xs) = Right (x,xs) Az előzőleg bevezetett do-jelölést használva így is felírhatjuk: mapa f = proc xs case xs of [ ] returna [ ] z : zs do y f z ys mapa f zs returna y : ys Az olyan arrow-kat vár, amelyeknek azonos típusú a kimenete. Viszont Either használatával ez a kényszer is feloldható: class Arrow arr ArrowChoice arr where (+++) :: arr a b arr c d arr (Either a c) (Either b d) A +++ gyakorlatilag úgy viszonyul a -hoz, mint a a &-hoz, és gyakorlatilag ezek duálisainak is tekinthetők, ha az arrow-k irányát megfordítjuk, és az Either típusokat párokra cseréljük. új definíciója tehát: f g = f +++ g > arr join where join (Left b) = b join (Right b) = b És az analógia tovább is vihető: definiálhatunk a first mintájára egy left kombinátort, amely csak a Left-be csomagolt értékeket küldi át a paraméterül kapott arrow-n, a többit változatlanul továbbadja: class Arrow arr ArrowChoice arr where left :: arr a b arr (Either a c) (Either b c) 10

11 Ezzel definiálható a second-nak megfelelő right is: right f = arr mirror > left f > arr mirror where mirror (Left a) = Right a mirror (Right a) = Left a És ezek után +++ egyszerűen kifejezhető: f +++ g = left f > right g Az Control.Arrow-ban található ArrowChoice osztály ezeket az operátorokat definiálja az ifte kivételével. Látható, hogy a left implementálásával a többit rögtön meg is kaphatjuk. Mind a függvények, mind a Kleisli arrow-k példányai ennek az osztálynak is: instance ArrowChoice ( ) where left f (Left a) = Left (f a) left f (Right b) = Right b instance Monad m ArrowChoice (Kleisli m) where left (Kleisli f ) = Kleisli $ λx case x of Left a do b f a return $ Left b Right b return $ Right b Így látszik, hogy a fent definiált mapa a map és a mapm közös általánosítása, például a következő két kifejezés kiértékelésekor: mapa (arr (+1)) [1..5] runkleisli (mapa (Kleisli print) > Kleisli print) [1.. 5] Az adatfolyamoknál viszont nem ilyen egyszerű a helyzet. Kiszűrhetjük a Left-be csomagolt értékeket, és átadhatjuk az f arrow-nak, de nem tudjuk az eredményt értelmesen összefésülni a Right csomagokkal! Csak úgy oldható meg a probléma, ha szűkítjük a lehetséges függvények körét. Az egyik lehetőség az, hogy csak a szinkron függvényekkel foglalkozunk, amelyek minden bemenetre egy kimenetet produkálnak, azaz hossztartók. Így már magától értetődő a megvalósítás: instance ArrowChoice SF where left (SF f ) = SF $ λxs combine xs $ f [y Left y xs ] where combine (Left y : xs) (z : zs) = Left z : combine xs zs combine (Right y : xs) zs = Right y : combine xs zs combine [ ] zs = [ ] A hossztartás nem csak a left definiálása miatt fontos. Ez a tulajdonság a first működését is megregulázza, ugyanis az általános esetben nem teljesíti (az itt nem említett) arrow-törvényeket, így meglepően viselkedhet. Sajnos az is nyilvánvaló, hogy a delay nem hossztartó, ám ezen könnyű segíteni a lista utolsó elemét elhagyó init függvénnyel: Példafutás: delay x = SF $ init (x:) runsf (mapa $ delay 0) [[1..3], [4..6], [7..9]] [[0, 0, 0], [1, 2, 3], [4, 5, 6]] Magasabbrendű arrow-k Próbáljuk meg bevezetni a $ operátor arrow-alapú megfelelőjét! Mivel a meglevő kombinátorokkal ez lehetetlen, származtassunk le egy újabb osztályt: class Arrow arr ArrowApply arr where app :: arr (arr a b,a) b 11

12 Ezt könnyű példányosítani függvényekre és Kleisli arrow-kra: instance ArrowApply ( ) where app (f,x) = f x instance Monad m ArrowApply (Kleisli m) where app = Kleisli (λ(kleisli f,x) f x) Viszont az adatfolyamok már nem tudják ezt a műveletet biztosítani! A probléma gyökere az, hogy maguk a folyamokon továbbított adatok már nem folyamok pontosabban lehetnek azok, de ezek teljesen függetlenek a továbbító közegüktől (ha esetleg a folyamon cseles módon saját magára mutató referenciákat akarnánk továbbítani, végtelen típust kapnánk, így le sem fordulhatna a programunk). Mivel az arrow-k ezeken az adatokon dolgoznak, magukra a folyamokra nincs rálátásuk (azaz a teljes folyamhoz nem férnek hozzá), így nincs értelmes megvalósítása az app műveletnek. Természetesen lehet olyan műveletet definiálni, amelynek megfelelő a típusa, csak sok hasznunk nem származik belőle. Egy példa: instance ArrowApply SF where app = SF $ concat (map (λ(sf f,x) f [x ])) Látszik, hogy némi trükközésre van szükség, hogy egyáltalán futtatható kódot kapjunk. A bejövő adatokat formálisan folyammá kell alakítani, ami ebben az esetben csak abból áll, hogy egyelemű listaként kötjük be őket a szintén a bemeneten kapott arrow-ba. Ezzel viszont pont az állapottal rendelkező arrow-k vesztik értelmüket, hiszen csak az első időpillanatuk jöhet létre. Másszóval csak a tiszta függvényekből arr-ral létrehozott arrow-k fognak a tőlük elvárható módon működni ebben a környezetben. Be lehet látni, hogy az app segítségével a first és a left is kifejezhető, így ezeknél nagyobb a kifejezőereje: first f = arr (λ(a,b) (f > arr (λx (x,b)),a)) > app left f = arr (λab case ab of Left Right (arr (λ(left x) x) > f > arr Left,ab) (arr (λ(right x) Right x),ab)) > app Az app kombinátor annyira sokoldalú, hogy az őt támogató arrow-k monádokká is alakíthatók! A számításokat bemenet nélküli arrow-val modellezzük: newtype ArrowMonad arr a = ArrowMonad (arr () a) Ezután a return és a >= implementációjára van szükség: instance ArrowApply a Monad (ArrowMonad a) where return x = ArrowMonad $ arr (const x) ArrowMonad m >= f = ArrowMonad $ m > arr (λx let ArrowMonad h = f x in (h, ())) > app Az alapelv egyszerű: f egy arrow-t ad vissza, amelyet kicsomagolunk és egy () kíséretében az app-nak átadunk. Ebből is látszik, hogy azok az arrow-k az érdekesek, amelyek nem támogatják az app műveletet, mivel ellenkező esetben célszerű közvetlenül monádokat használni. Felhasznált források 1. John Hughes: Programming with Arrows, in 5th International Summer School on Advanced Functional Programming, LNCS 3622, pp , Springer, Ross Paterson: A New Notation for Arrows, in ICFP 2001, Firenze, Italy, pp My Evolution as a Haskell Programmer: Factorial with Arrows 4. Arrows in Haskell: bumpy first steps 5. ArrowLoop 12

Funkcionális Nyelvek 2 (MSc)

Funkcionális Nyelvek 2 (MSc) Funkcionális Nyelvek 2 (MSc) Páli Gábor János pgj@elte.hu Eötvös Loránd Tudományegyetem Informatikai Kar Programozási Nyelvek és Fordítóprogramok Tanszék Tematika A (tervezett) tematika rövid összefoglalása

Részletesebben

FUNKCIONÁLIS PROGRAMOZÁS

FUNKCIONÁLIS PROGRAMOZÁS FUNKCIONÁLIS PROGRAMOZÁS A funkcionális programozás néhány jellemzője Funkcionális programozás 1-2 Funkcionális, más néven applikatív programozás Funkcionális = függvényalapú, függvényközpontú Applikatív

Részletesebben

Programozás burritokkal

Programozás burritokkal Monádok (folytatás) Programozás burritokkal [2..21] Programozás monádokkal: Programstrukturálás type IO α = World (α, World) -- putstr :: String IO () -- getline :: IO String (>>=) :: IO α (α IO β) IO

Részletesebben

FUNKCIONÁLIS PROGRAMOZÁS GYAKORLAT JEGYZET

FUNKCIONÁLIS PROGRAMOZÁS GYAKORLAT JEGYZET FUNKCIONÁLIS PROGRAMOZÁS GYAKORLAT JEGYZET Szerkesztette: Balogh Tamás 2013. május 17. Ha hibát találsz, kérlek jelezd a info@baloghtamas.hu e-mail címen! Ez a Mű a Creative Commons Nevezd meg! - Ne add

Részletesebben

2018, Funkcionális programozás

2018, Funkcionális programozás Funkcionális programozás 3. előadás Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2018, tavaszi félév Miről volt szó? A Haskell programozási nyelv főbb

Részletesebben

Tulajdonságalapú tesztelés

Tulajdonságalapú tesztelés Tulajdonságalapú tesztelés QuickCheck A QuickCheck Haskell programok automatikus, tulajdonságalapú tesztelésére használható. Programspecifikáció: program által teljesítendő tulajdonságok Nagy számú, a

Részletesebben

Tisztán funkcionális adatszerkezetek

Tisztán funkcionális adatszerkezetek Tisztán funkcionális adatszerkezetek Bevezetés A hatékony adatszerkezetek általában... [..] language-independent only in the sense of Henry Ford: Programmers can use any language as they want, as long

Részletesebben

2019, Funkcionális programozás. 2. el adás. MÁRTON Gyöngyvér

2019, Funkcionális programozás. 2. el adás. MÁRTON Gyöngyvér Funkcionális programozás 2. el adás Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2019, tavaszi félév Mir l volt szó? Követelmények, osztályozás Programozási

Részletesebben

C++ referencia. Izsó Tamás február 17. A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák:

C++ referencia. Izsó Tamás február 17. A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák: C++ referencia Izsó Tamás 2017. február 17. 1. Bevezetés A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák: Sokan összetévesztik a pointerrel. Keveset alkalmazzák

Részletesebben

Már megismert fogalmak áttekintése

Már megismert fogalmak áttekintése Interfészek szenasi.sandor@nik.bmf.hu PPT 2007/2008 tavasz http://nik.bmf.hu/ppt 1 Témakörök Polimorfizmus áttekintése Interfészek Interfészek kiterjesztése Eseménykezelési módszerek 2 Már megismert fogalmak

Részletesebben

FUNKCIONÁLIS PROGRAMOZÁS ELŐADÁS JEGYZET

FUNKCIONÁLIS PROGRAMOZÁS ELŐADÁS JEGYZET FUNKCIONÁLIS PROGRAMOZÁS ELŐADÁS JEGYZET Szerkesztette: Balogh Tamás 2013. május 30. Ha hibát találsz, kérlek jelezd a info@baloghtamas.hu e-mail címen! Ez a Mű a Creative Commons Nevezd meg! - Ne add

Részletesebben

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon 1. Template (sablon) 1.1. Függvénysablon Maximum függvény megvalósítása függvénynév túlterheléssel. i n l i n e f l o a t Max ( f l o a t a, f l o a t b ) { return a>b? a : b ; i n l i n e double Max (

Részletesebben

Alapok. tisztán funkcionális nyelv, minden függvény (a konstansok is) nincsenek hagyományos változók, az első értékadás után nem módosíthatók

Alapok. tisztán funkcionális nyelv, minden függvény (a konstansok is) nincsenek hagyományos változók, az első értékadás után nem módosíthatók Haskell 1. Alapok tisztán funkcionális nyelv, minden függvény (a konstansok is) nincsenek hagyományos változók, az első értékadás után nem módosíthatók elég jól elkerülhetők így a mellékhatások könnyebben

Részletesebben

5. KOMBINÁCIÓS HÁLÓZATOK LEÍRÁSÁNAK SZABÁLYAI

5. KOMBINÁCIÓS HÁLÓZATOK LEÍRÁSÁNAK SZABÁLYAI 5. KOMBINÁCIÓS HÁLÓZATOK LEÍRÁSÁNAK SZABÁLYAI 1 Kombinációs hálózatok leírását végezhetjük mind adatfolyam-, mind viselkedési szinten. Az adatfolyam szintű leírásokhoz az assign kulcsszót használjuk, a

Részletesebben

2016, Funkcionális programozás

2016, Funkcionális programozás Funkcionális programozás 2. előadás Sapientia Egyetem, Műszaki és Humántudományok Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2016, tavaszi félév Miről volt szó? Programozási paradigmák: imperatív,

Részletesebben

Funkcionális és logikai programozás. { Márton Gyöngyvér, 2012} { Sapientia, Erdélyi Magyar Tudományegyetem }

Funkcionális és logikai programozás. { Márton Gyöngyvér, 2012} { Sapientia, Erdélyi Magyar Tudományegyetem } Funkcionális és logikai programozás { Márton Gyöngyvér, 2012} { Sapientia, Erdélyi Magyar Tudományegyetem } http://www.ms.sapientia.ro/~mgyongyi ` 1 Jelenlét: Követelmények, osztályozás Az első 4 előadáson

Részletesebben

Programok értelmezése

Programok értelmezése Programok értelmezése Kód visszafejtés. Izsó Tamás 2016. szeptember 22. Izsó Tamás Programok értelmezése/ 1 Section 1 Programok értelmezése Izsó Tamás Programok értelmezése/ 2 programok szemantika értelmezése

Részletesebben

2018, Funkcionális programozás

2018, Funkcionális programozás Funkcionális programozás 6. előadás Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2018, tavaszi félév Miről volt szó? Haskell modulok, kompilálás a

Részletesebben

Programozás II. 2. Dr. Iványi Péter

Programozás II. 2. Dr. Iványi Péter Programozás II. 2. Dr. Iványi Péter 1 C++ Bjarne Stroustrup, Bell Laboratórium Első implementáció, 1983 Kezdetben csak precompiler volt C++ konstrukciót C-re fordította A kiterjesztés alapján ismerte fel:.cpp.cc.c

Részletesebben

Occam 1. Készítette: Szabó Éva

Occam 1. Készítette: Szabó Éva Occam 1. Készítette: Szabó Éva Párhuzamos programozás Egyes folyamatok (processzek) párhuzamosan futnak. Több processzor -> tényleges párhuzamosság Egy processzor -> Időosztásos szimuláció Folyamatok közötti

Részletesebben

Interfészek. PPT 2007/2008 tavasz.

Interfészek. PPT 2007/2008 tavasz. Interfészek szenasi.sandor@nik.bmf.hu PPT 2007/2008 tavasz http://nik.bmf.hu/ppt 1 Témakörök Polimorfizmus áttekintése Interfészek Interfészek kiterjesztése 2 Már megismert fogalmak áttekintése Objektumorientált

Részletesebben

OOP. Alapelvek Elek Tibor

OOP. Alapelvek Elek Tibor OOP Alapelvek Elek Tibor OOP szemlélet Az OOP szemlélete szerint: a valóságot objektumok halmazaként tekintjük. Ezen objektumok egymással kapcsolatban vannak és együttműködnek. Program készítés: Absztrakciós

Részletesebben

Kifejezések. Kozsik Tamás. December 11, 2016

Kifejezések. Kozsik Tamás. December 11, 2016 Kifejezések Kozsik Tamás December 11, 2016 Kifejezések Lexika Szintaktika Szemantika Lexika azonosítók (változó-, metódus-, típus- és csomagnevek) literálok operátorok, pl. + zárójelek: (), [], {},

Részletesebben

GENERIKUS PROGRAMOZÁS Osztálysablonok, Általános felépítésű függvények, Függvénynevek túlterhelése és. Függvénysablonok

GENERIKUS PROGRAMOZÁS Osztálysablonok, Általános felépítésű függvények, Függvénynevek túlterhelése és. Függvénysablonok GENERIKUS PROGRAMOZÁS Osztálysablonok, Általános felépítésű függvények, Függvénynevek túlterhelése és Függvénysablonok Gyakorlatorientált szoftverfejlesztés C++ nyelven Visual Studio Community fejlesztőkörnyezetben

Részletesebben

Az UPPAAL egyes modellezési lehetőségeinek összefoglalása. Majzik István BME Méréstechnika és Információs Rendszerek Tanszék

Az UPPAAL egyes modellezési lehetőségeinek összefoglalása. Majzik István BME Méréstechnika és Információs Rendszerek Tanszék Az UPPAAL egyes modellezési lehetőségeinek összefoglalása Majzik István BME Méréstechnika és Információs Rendszerek Tanszék Résztvevők együttműködése (1) Automaták interakciói üzenetküldéssel Szinkron

Részletesebben

Kifejezések. Kozsik Tamás. December 11, 2016

Kifejezések. Kozsik Tamás. December 11, 2016 Kifejezések Kozsik Tamás December 11, 2016 Kifejezés versus utasítás C/C++: kifejezés plusz pontosvessző: utasítás kiértékeli a kifejezést jellemzően: mellékhatása is van például: értékadás Ada: n = 5;

Részletesebben

Programozási alapismeretek 4.

Programozási alapismeretek 4. Programozási alapismeretek 4. Obejktum-Orientált Programozás Kis Balázs Bevezetés I. Az OO programozási szemlélet, egy merőben más szemlélet, az összes előző szemlélettel (strukturális, moduláris, stb.)

Részletesebben

és az instanceof operátor

és az instanceof operátor Java VIII. Az interfacei és az instanceof operátor Krizsán Zoltán Miskolci Egyetem Általános Informatikai Tanszék Utolsó módosítás: 2005. 10. 24. Java VIII.: Interface JAVA8 / 1 Az interfészről általában

Részletesebben

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán Java VIII. Az interfacei és az instanceof operátor Krizsán Zoltán Miskolci Egyetem Általános Informatikai Tanszék Utolsó módosítás: 2005. 10. 24. Java VIII.: Interface JAVA8 / 1 Az interfészről általában

Részletesebben

Oktatási segédlet 2014

Oktatási segédlet 2014 Oktatási segédlet 2014 A kutatás a TÁMOP 4.2.4.A/2-11-1-2012- 0001 azonosító számú Nemzeti Kiválóság Program Hazai hallgatói, illetve kutatói személyi támogatást biztosító rendszer kidolgozása és működtetése

Részletesebben

2019, Funkcionális programozás. 4. el adás. MÁRTON Gyöngyvér

2019, Funkcionális programozás. 4. el adás. MÁRTON Gyöngyvér Funkcionális programozás 4. el adás Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2019, tavaszi félév Mir l volt szó? GHC parancsok fenntartott szavak

Részletesebben

BASH SCRIPT SHELL JEGYZETEK

BASH SCRIPT SHELL JEGYZETEK BASH SCRIPT SHELL JEGYZETEK 1 TARTALOM Paraméterek... 4 Változók... 4 Környezeti változók... 4 Szűrők... 4 grep... 4 sed... 5 cut... 5 head, tail... 5 Reguláris kifejezések... 6 *... 6 +... 6?... 6 {m,n}...

Részletesebben

Java programozási nyelv

Java programozási nyelv Java programozási nyelv 2. rész Vezérlő szerkezetek Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor 2005. szeptember A Java programozási nyelv Soós Sándor 1/23 Tartalomjegyzék

Részletesebben

1. Egyszerű (primitív) típusok. 2. Referencia típusok

1. Egyszerű (primitív) típusok. 2. Referencia típusok II. A Java nyelv eszközei 1. Milyen eszközöket nyújt a Java a programozóknak Korábban már említettük, hogy a Java a C nyelvből alakult ki, ezért a C, C++ nyelvben járatos programozóknak nem fog nehézséget

Részletesebben

List<String> l1 = new ArrayList<String>(); List<Object> l2 = l1; // error

List<String> l1 = new ArrayList<String>(); List<Object> l2 = l1; // error Generics Egyszerűbb példák (java.util csomagból): public interface List { void add(e x); Iterator iterator(); public interface Iterator { E next(); boolean hasnext(); E - formális típusparaméter,

Részletesebben

Programozási nyelvek Java

Programozási nyelvek Java Programozási nyelvek Java Kozsik Tamás előadása alapján Készítette: Nagy Krisztián 9. előadás Interface - típust vezet be, de osztálypéldány nem készíthető belőle (statikus típust ad) - több osztály is

Részletesebben

Diszkrét matematika II., 8. előadás. Vektorterek

Diszkrét matematika II., 8. előadás. Vektorterek 1 Diszkrét matematika II., 8. előadás Vektorterek Dr. Takách Géza NyME FMK Informatikai Intézet takach@inf.nyme.hu http://inf.nyme.hu/ takach/ 2007.??? Vektorterek Legyen T egy test (pl. R, Q, F p ). Definíció.

Részletesebben

Differenciálegyenletek. Vajda István március 4.

Differenciálegyenletek. Vajda István március 4. Analízis előadások Vajda István 2009. március 4. Függvényegyenletek Definíció: Az olyan egyenleteket, amelyekben a meghatározandó ismeretlen függvény, függvényegyenletnek nevezzük. Függvényegyenletek Definíció:

Részletesebben

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*; Java osztály készítése, adattagok, és metódusok, láthatóság, konstruktor, destruktor. Objektum létrehozása, használata, öröklés. ( Előfeltétel 12. Tétel ) Az osztály egy olyan típus leíró struktúra, amely

Részletesebben

S0-02 Típusmodellek (Programozás elmélet)

S0-02 Típusmodellek (Programozás elmélet) S0-02 Típusmodellek (Programozás elmélet) Tartalom 1. Absztrakt adattípus 2. Adattípus specifikációja 3. Adattípus osztály 4. Paraméterátadás 5. Reprezentációs függvény 6. Öröklődés és polimorfizmus 7.

Részletesebben

Programozási nyelvek Java

Programozási nyelvek Java Programozási nyelvek Java 11.gyakorlat Operációsrendszertől függő tulajdonságok PATH elválasztó Unix ":" Windows ";" final String PATH_SEPARATOR = File.pathSeparator; Ugyanaz, csak karakterkent final char

Részletesebben

S z á m í t ó g é p e s a l a p i s m e r e t e k

S z á m í t ó g é p e s a l a p i s m e r e t e k S z á m í t ó g é p e s a l a p i s m e r e t e k 7. előadás Ami eddig volt Számítógépek architektúrája Alapvető alkotóelemek Hardver elemek Szoftver Gépi kódtól az operációs rendszerig Unix alapok Ami

Részletesebben

Java és web programozás

Java és web programozás Budapesti Műszaki Egyetem 2015. 02. 11. 2. Előadás Mese Néhány programozási módszer: Idők kezdetén való programozás Struktúrált Moduláris Funkcionális Objektum-orientált... Mese Néhány programozási módszer:

Részletesebben

Óbudai Egyetem. C programozási nyelv

Óbudai Egyetem. C programozási nyelv Óbudai Egyetem Kandó Kálmán Villamosmérnöki Kar C programozási nyelv Struktúrák és Unionok Dr. Schuster György 2016. október 6. Óbudai Egyetem Kandó Kálmán Villamosmérnöki Kar C programozási 2016. októbernyelv

Részletesebben

2018, Funkcionális programozás

2018, Funkcionális programozás Funkcionális programozás 7. előadás Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2018, tavaszi félév Miről volt szó? összefésüléses rendezés (merge

Részletesebben

OOP #14 (referencia-elv)

OOP #14 (referencia-elv) OOP #14 (referencia-elv) v1.0 2003.03.19. 21:22:00 Eszterházy Károly Főiskola Információtechnológia tsz. Hernyák Zoltán adj. e-mail: aroan@ektf.hu web: http://aries.ektf.hu/~aroan OOP OOP_14-1 - E jegyzet

Részletesebben

Programozás C és C++ -ban

Programozás C és C++ -ban Programozás C és C++ -ban 2. További különbségek a C és C++ között 2.1 Igaz és hamis A C++ programozási nyelv a C-hez hasonlóan definiál néhány alap adattípust: char int float double Ugyanakkor egy új

Részletesebben

C++ programozási nyelv

C++ programozási nyelv C++ programozási nyelv Gyakorlat - 8. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor 2004. november A C++ programozási nyelv Soós Sándor 1/12 Tartalomjegyzék Miért

Részletesebben

First Prev Next Last Go Back Full Screen Close Quit

First Prev Next Last Go Back Full Screen Close Quit Valós függvények (2) (Határérték) 1. A a R szám δ > 0 sugarú környezete az (a δ, a + δ) nyílt intervallum. Ezután a valós számokat, a számegyenesen való ábrázolhatóságuk miatt, pontoknak is fogjuk hívni.

Részletesebben

Párhuzamos programozás Haskellben (folytatás)

Párhuzamos programozás Haskellben (folytatás) Párhuzamos programozás Haskellben (folytatás) Mit tudtunk meg eddig a párhuzamos programokról? Párhuzamos programozással gyorsíthatunk a programon, miközben megőrizzük a determinisztikusságát. Teljesen

Részletesebben

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben? 1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben? 3. Ismertesse a névtér fogalmát! 4. Mit értünk a "változó hatóköre"

Részletesebben

Programozási nyelvek (ADA)

Programozási nyelvek (ADA) Programozási nyelvek (ADA) Kozsik Tamás előadása alapján Készítette: Nagy Krisztián 3. előadás Programozási nyelv felépítése szabályok megadása Lexika Milyen egységek építik fel? Szintaktikus szabályok

Részletesebben

3. Lineáris differenciálegyenletek

3. Lineáris differenciálegyenletek 3. Lineáris differenciálegyenletek A közönséges differenciálegyenletek két nagy csoportba oszthatók lineáris és nemlineáris egyenletek csoportjába. Ez a felbontás kicsit önkényesnek tűnhet, a megoldásra

Részletesebben

C programozási nyelv

C programozási nyelv C programozási nyelv Struktúrák Dr Schuster György 2011 június 16 Dr Schuster György () C programozási nyelv Struktúrák 2011 június 16 1 / 11 Struktúrák Struktúrák A struktúra egy olyan összetett adatszerkezet,

Részletesebben

A programozás alapjai 1 Rekurzió

A programozás alapjai 1 Rekurzió A programozás alapjai Rekurzió. előadás Híradástechnikai Tanszék - preorder (gyökér bal gyerek jobb gyerek) mentés - visszaállítás - inorder (bal gyerek gyökér jobb gyerek) rendezés 4 5 6 4 6 7 5 7 - posztorder

Részletesebben

Adatszerkezetek és algoritmusok

Adatszerkezetek és algoritmusok 2009. november 13. Ismétlés El z órai anyagok áttekintése Ismétlés Specikáció Típusok, kifejezések, m veletek, adatok ábrázolása, típusabsztakció Vezérlési szerkezetek Függvények, paraméterátadás, rekurziók

Részletesebben

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi.

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi. Függvények 1.Függvények...1 1.1.A függvény deníció szintaxisa... 1..Függvények érték visszatérítése...3 1.3.Környezettel kapcsolatos kérdések...4 1.4.Lokális változók használata...4 1.5.Rekurzív hívások...5.kód

Részletesebben

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra Programozás II. 2. gyakorlat Áttérés C-ről C++-ra Tartalom Új kommentelési lehetőség Változók deklarációjának helye Alapértelmezett függvényparaméterek Névterek I/O műveletek egyszerűsödése Logikai adattípus,

Részletesebben

S2-01 Funkcionális nyelvek alapfogalmai

S2-01 Funkcionális nyelvek alapfogalmai S2-01 Funkcionális nyelvek alapfogalmai Tartalom 1. Funkcionális nyelvek alapfogalmai Modell Kiértékelés Curry-zés Magasabbrendű függvények Listák Tisztaság 2. Típusok Algebrai adattípusok Típusosztályok

Részletesebben

Java programozási nyelv 5. rész Osztályok III.

Java programozási nyelv 5. rész Osztályok III. Java programozási nyelv 5. rész Osztályok III. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor 2005. szeptember A Java programozási nyelv Soós Sándor 1/20 Tartalomjegyzék

Részletesebben

NAGYPONTOSSÁGÚ EGÉSZ-ARITMETIKA TARTALOM

NAGYPONTOSSÁGÚ EGÉSZ-ARITMETIKA TARTALOM NAGYPONTOSSÁGÚ EGÉSZ-ARITMETIKA TARTALOM 0. A feladat... 2 1. Az Egész számok ábrázolásai... 2 2. A műveletek szignatúrája... 3 3. A keretprogram... 4 4. Technikai tanácsok... 7 5. Elegancianövelő lehetőségek

Részletesebben

sallang avagy Fordítótervezés dióhéjban Sallai Gyula

sallang avagy Fordítótervezés dióhéjban Sallai Gyula sallang avagy Fordítótervezés dióhéjban Sallai Gyula Az előadás egy kis példaprogramon keresztül mutatja be fordítók belső lelki világát De mit is jelent, az hogy fordítóprogram? Mit csinál egy fordító?

Részletesebben

Tisztán funkcionális adatszerkezetek (folytatás)

Tisztán funkcionális adatszerkezetek (folytatás) Tisztán funkcionális adatszerkezetek (folytatás) FingerTree (intuíció) [2..26] FingerTree (intuíció) [3..26] FingerTree (intuíció) [4..26] FingerTree (intuíció) [5..26] FingerTree (intuíció) [6..26] FingerTree

Részletesebben

2019, Funkcionális programozás. 5. el adás. MÁRTON Gyöngyvér

2019, Funkcionális programozás. 5. el adás. MÁRTON Gyöngyvér Funkcionális programozás 5. el adás Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2019, tavaszi félév Mir l volt szó? a Haskell kiértékelési stratégiája

Részletesebben

Vezérlési szerkezetek

Vezérlési szerkezetek Vezérlési szerkezetek Szelekciós ok: if, else, switch If Segítségével valamely ok végrehajtását valamely feltétel teljesülése esetén végezzük el. Az if segítségével valamely tevékenység () végrehajtását

Részletesebben

Hurokegyenlet alakja, ha az áram irányával megegyező feszültségeséseket tekintjük pozitívnak:

Hurokegyenlet alakja, ha az áram irányával megegyező feszültségeséseket tekintjük pozitívnak: Első gyakorlat A gyakorlat célja, hogy megismerkedjünk Matlab-SIMULINK szoftverrel és annak segítségével sajátítsuk el az Automatika c. tantárgy gyakorlati tananyagát. Ezen a gyakorlaton ismertetésre kerül

Részletesebben

A Feldspar fordító, illetve Feldspar programok tesztelése

A Feldspar fordító, illetve Feldspar programok tesztelése A Feldspar fordító, illetve Feldspar programok tesztelése [KMOP-1.1.2-08/1-2008-0002 társfinanszírozó: ERFA] Leskó Dániel Eötvös Loránd Tudományegyetem Programozási Nyelvek és Fordítóprogramok Tanszék

Részletesebben

Programozás C++ -ban 2007/1

Programozás C++ -ban 2007/1 Programozás C++ -ban 2007/1 1. Különbségek a C nyelvhez képest Több alapvető különbség van a C és a C++ programozási nyelvek szintaxisában. A programozó szempontjából ezek a különbségek könnyítik a programozó

Részletesebben

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok A szemantikus elemzés helye Forrásprogram Forrás-kezelő (source handler) Lexikális elemző (scanner) A szemantikus elemzés feladatai Fordítóprogramok előadás (A, C, T szakirány) Szintaktikus elemző (parser)

Részletesebben

ABSZTRAKCIÓ FÜGGVÉNYEKKEL (ELJÁRÁSOKKAL)

ABSZTRAKCIÓ FÜGGVÉNYEKKEL (ELJÁRÁSOKKAL) ABSZTRAKCIÓ FÜGGVÉNYEKKEL (ELJÁRÁSOKKAL) Elágazó rekurzió Absztrakció függvényekkel (eljárásokkal) FP-5..7-2 Korábban lineáris-rekurzív, ill. lineáris-iteratív folyamatokra láttunk példákat (faktoriális

Részletesebben

A digitális számítás elmélete

A digitális számítás elmélete A digitális számítás elmélete 8. előadás ápr. 16. Turing gépek és nyelvtanok A nyelvosztályok áttekintése Turing gépek és a természetes számokon értelmezett függvények Áttekintés Dominó Bizonyítások: L

Részletesebben

Programozás C++ -ban 2007/7

Programozás C++ -ban 2007/7 Programozás C++ -ban 2007/7 1. Másoló konstruktor Az egyik legnehezebben érthető fogalom C++ -ban a másoló konstruktor, vagy angolul "copy-constructor". Ez a konstruktor fontos szerepet játszik az argumentum

Részletesebben

Szkriptnyelvek. 1. UNIX shell

Szkriptnyelvek. 1. UNIX shell Szkriptnyelvek 1. UNIX shell Szkriptek futtatása Parancsértelmez ő shell script neve paraméterek shell script neve paraméterek Ebben az esetben a szkript tartalmazza a parancsértelmezőt: #!/bin/bash Szkriptek

Részletesebben

FÜGGVÉNYTANI ALAPOK A) ÉRTELMEZÉSI TARTOMÁNY

FÜGGVÉNYTANI ALAPOK A) ÉRTELMEZÉSI TARTOMÁNY FÜGGVÉNYTANI ALAPOK Foglalkoztunk az alaptulajdonságnak tekinthető értelmezési tartománnyal, és a paritással, továbbá az összetett függvények képzési módjával, illetve ezeknek az elemi függvényekre való

Részletesebben

Java II. I A Java programozási nyelv alapelemei

Java II. I A Java programozási nyelv alapelemei Java II. I A Java programozási nyelv alapelemei Miskolci Egyetem Általános Informatikai Tanszék Utolsó módosítás: 2008. 02. 19. Java II.: Alapelemek JAVA2 / 1 A Java formalizmusa A C, illetve az annak

Részletesebben

Programozási technológia

Programozási technológia Programozási technológia Generikus osztályok Gyűjtemények Dr. Szendrei Rudolf ELTE Informatikai Kar 2018. Generikus osztályok Javaban az UML paraméteres osztályainak a generikus (sablon) osztályok felelnek

Részletesebben

C programozási nyelv

C programozási nyelv C programozási nyelv Előfeldolgozó utasítások Dr Schuster György 2011 május 3 Dr Schuster György () C programozási nyelv Előfeldolgozó utasítások 2011 május 3 1 / 15 A fordítás menete Dr Schuster György

Részletesebben

Programozási nyelvek (ADA)

Programozási nyelvek (ADA) Programozási nyelvek (ADA) Kozsik Tamás előadása alapján Készítette: Nagy Krisztián 1. előadás Hasznos weboldal http://kto.web.elte.hu Program felépítése Programegységek (program unit) eljárások (procedure)

Részletesebben

2016, Funkcionális programozás

2016, Funkcionális programozás Funkcionális programozás 11. előadás Sapientia Egyetem, Műszaki és Humántudományok Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2016, tavaszi félév Miről volt szó? Haskell I/O műveletek, feladatok:

Részletesebben

NEM-DETERMINISZTIKUS PROGRAMOK HELYESSÉGE. Szekvenciális programok kategóriái. Hoare-Dijkstra-Gries módszere

NEM-DETERMINISZTIKUS PROGRAMOK HELYESSÉGE. Szekvenciális programok kategóriái. Hoare-Dijkstra-Gries módszere Szekvenciális programok kategóriái strukturálatlan strukturált NEM-DETERMINISZTIKUS PROGRAMOK HELYESSÉGE Hoare-Dijkstra-Gries módszere determinisztikus valódi korai nem-determinisztikus általános fejlett

Részletesebben

Python tanfolyam Python bevezető I. rész

Python tanfolyam Python bevezető I. rész Python tanfolyam Python bevezető I. rész Mai tematika Amiről szó lesz (most): Interpretált vs. fordított nyelvek, GC Szintakszis Alaptípusok Control flow: szekvencia, szelekció, iteráció... Függvények

Részletesebben

S01-8 Komponens alapú szoftverfejlesztés 2

S01-8 Komponens alapú szoftverfejlesztés 2 S01-8 Komponens alapú szoftverfejlesztés 2 Tartalom 1. Komponens megvalósítása: kölcsönhatás modell, viselkedési vagy algoritmikus modell és strukturális modell. 2. Komponens megtestesítés: finomítás és

Részletesebben

BASH script programozás II. Vezérlési szerkezetek

BASH script programozás II. Vezérlési szerkezetek 06 BASH script programozás II. Vezérlési szerkezetek Emlékeztető Jelölésbeli különbség van parancs végrehajtása és a parancs kimenetére való hivatkozás között PARANCS $(PARANCS) Jelölésbeli különbség van

Részletesebben

Globális operátor overloading

Globális operátor overloading Programozás II. 9. gyakorlat Operátor overloading 2: Unáris operátorok, globálisan megvalósított operátorok, > operátorok Kivételkezelés, IO library Globális operátor overloading Előző alkalommal

Részletesebben

A PiFast program használata. Nagy Lajos

A PiFast program használata. Nagy Lajos A PiFast program használata Nagy Lajos Tartalomjegyzék 1. Bevezetés 3 2. Bináris kimenet létrehozása. 3 2.1. Beépített konstans esete.............................. 3 2.2. Felhasználói konstans esete............................

Részletesebben

Osztálytervezés és implementációs ajánlások

Osztálytervezés és implementációs ajánlások Osztálytervezés és implementációs ajánlások Miskolci Egyetem Általános Informatikai Tanszék Utolsó módosítás: 2006. 04. 24. Osztálytervezés és implementációs kérdések OTERV / 1 Osztály tervezés Egy nyelv

Részletesebben

Osztálytervezés és implementációs ajánlások

Osztálytervezés és implementációs ajánlások Osztálytervezés és implementációs ajánlások Miskolci Egyetem Általános Informatikai Tanszék Utolsó módosítás: 2006. 04. 24. Osztálytervezés és implementációs kérdések OTERV / 1 Osztály tervezés Egy nyelv

Részletesebben

Határozatlan integrál (2) First Prev Next Last Go Back Full Screen Close Quit

Határozatlan integrál (2) First Prev Next Last Go Back Full Screen Close Quit Határozatlan integrál () First Prev Next Last Go Back Full Screen Close Quit 1. Az összetett függvények integrálására szolgáló egyik módszer a helyettesítéssel való integrálás. Az idevonatkozó tétel pontos

Részletesebben

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok. Eötvös Loránd Tudományegyetem Informatikai Kar Alkalmazott modul: Programozás 4. előadás Procedurális programozás: iteratív és rekurzív alprogramok Giachetta Roberto groberto@inf.elte.hu http://people.inf.elte.hu/groberto

Részletesebben

Statikus adattagok. Statikus adattag inicializálása. Speciális adattagok és tagfüggvények. Általános Informatikai Tanszék

Statikus adattagok. Statikus adattag inicializálása. Speciális adattagok és tagfüggvények. Általános Informatikai Tanszék Speciális adattagok és tagfüek Miskolci Egyetem Általános Informatikai Tanszék CPP7 / 1 Statikus adattagok Bármely adattag lehet static tárolási osztályú A statikus adattag az osztály valamennyi objektuma

Részletesebben

Osztályok. construct () destruct() $b=new Book(); $b=null; unset ($b); book.php: <?php class Book { private $isbn; public $title;

Osztályok. construct () destruct() $b=new Book(); $b=null; unset ($b); book.php: <?php class Book { private $isbn; public $title; PHP5 objektumok 1 Osztályok class, new book.php: construct () destruct() $b=new Book(); törlés: $b=null; vagy unset ($b); -elnevezési konvenciók private $isbn; public $title; function

Részletesebben

Operációs Rendszerek II. labor. 2. alkalom

Operációs Rendszerek II. labor. 2. alkalom Operációs Rendszerek II. labor 2. alkalom Mai témák (e)grep Shell programozás (részletesebben, példákon keresztül) grep Alapvető működés: mintákat keres a bemeneti csatorna (STDIN vagy fájl) soraiban,

Részletesebben

Eseménykezelés. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor.

Eseménykezelés. Szoftvertervezés és -fejlesztés II. előadás.   Szénási Sándor. Eseménykezelés előadás http://nik.uni-obuda.hu/sztf2 Szénási Sándor szenasi.sandor@nik.uni-obuda.hu Óbudai Egyetem,Neumann János Informatikai Kar Függvénymutatókkal Származtatással Interfészekkel Egyéb

Részletesebben

Programozási nyelvek JAVA EA+GY 1. gyakolat

Programozási nyelvek JAVA EA+GY 1. gyakolat Programozási nyelvek JAVA EA+GY 1. gyakolat EÖTVÖS LORÁND TUDOMÁNYEGYTEM INFORMATIKAI KAR PROGRAMOZÁSI NYELVEK ÉS FORDÍTÓPROGRAMOK TANSZÉK 2018/2019. tavaszi félév Tartalom 1 A Java alapjai 2 Java program

Részletesebben

Java programozási nyelv 4. rész Osztályok II.

Java programozási nyelv 4. rész Osztályok II. Java programozási nyelv 4. rész Osztályok II. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor 2005. szeptember A Java programozási nyelv Soós Sándor 1/17 Tartalomjegyzék

Részletesebben

Egyenletek, egyenlőtlenségek X.

Egyenletek, egyenlőtlenségek X. Egyenletek, egyenlőtlenségek X. DEFINÍCIÓ: (Logaritmus) Ha egy pozitív valós számot adott, 1 - től különböző pozitív alapú hatvány alakban írunk fel, akkor ennek a hatványnak a kitevőjét logaritmusnak

Részletesebben

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással Pázmány Péter Katolikus Egyetem Információs Technológiai és Bionikai Kar Bevezetés a Programozásba II 2. előadás Adattípusok megvalósítása egységbe zárással 2014.02.17. Giachetta Roberto groberto@inf.elte.hu

Részletesebben

ELTE SAP Excellence Center Oktatóanyag 1

ELTE SAP Excellence Center Oktatóanyag 1 Oktatóanyag 1 Oktatóanyag 2 Az oktatás folyamán használt példák a fent látható egyszerű modell implementációi. Oktatóanyag 3 A definíciós részben definiálja a fejlesztő az egyes attribútumokat, metódusokat,

Részletesebben

Diszkrét matematika I., 12. előadás Dr. Takách Géza NyME FMK Informatikai Intézet takach november 30.

Diszkrét matematika I., 12. előadás Dr. Takách Géza NyME FMK Informatikai Intézet   takach november 30. 1 Diszkrét matematika I, 12 előadás Dr Takách Géza NyME FMK Informatikai Intézet takach@infnymehu http://infnymehu/ takach 2005 november 30 Vektorok Definíció Egy tetszőleges n pozitív egész számra n-komponensű

Részletesebben

Objektumorientált programozás C# nyelven

Objektumorientált programozás C# nyelven Objektumorientált programozás C# nyelven 2. rész Öröklés és többalakúság Nemvirtuális metódusok, elrejtés Virtuális metódusok, elrejtés Típuskényszerítés, az is és as operátorok Absztrakt osztályok, absztrakt

Részletesebben