Minulý týden (26-31.1.2009) jsem trávil v Mnichově na pravidelné programátorské konferenci OOP. Událost to byla vskutku grandiózní, každý den probíhalo souběžně několik přednášek na žhavá současná témata z oblasti objektově orientovaného programování a z přilehlých oblastí, prokládaných keynotes, čili odlehčenými prezentacemi celebrit z oboru. První den jsem podstoupil celodenní školení v oblasti, o které jsem doposud věděl velmi málo, nicméně která mě podvědomě lákala - Domain-Specific Languages. Konkrétně se jednalo o přednášku Domain-Specific Modeling: Enabling full code generation, kterou přednesl Fin Juha-Pekka Tolvanen1). V následujícím textu se pokusím srozumitelně shrnout, co jsem si z této přednášky odnesl.
V současnosti lze vysledovat dva protichůdné trendy v návrhu programovacích jazyků. V prvním z nich je patrná snaha o zlepšení vyjadřovacích schopností jazyka a elegance zápisu. Jako příklad vezměme jazyk Scala, který díky svým jazykovým prvkům jako jsou traits, mixins, function values a silná typová kontrola, otevírá architektům, designerům a vývojářům nové obzory. O tom však v nějakém příštím blogu.
V druhém proudu se naopak klade důraz na schopnost jazyka vyjádřit vazby a interakce v systémech pouze z jedné konkrétní oblasti (domény) a redukovat počet stupňů volnosti jazyka. V takovém jazyce se operuje s pojmy, kterým rozumí specialisté z dané oblasti, z čehož plyne řada blahodárných důsledků, např. usnadnění komunikace během vývoje produktu.
Uvažujme fiktivního výrobce digitálních hodinek, kterému po té, co uvedl na trh několik modelů hodinek, začíná být jasné, že při vývoji programového vybavení se opakovaně používají stejné moduly, jako např. čas, budík, stopky, tlačítka, display atd. Navíc se zdá, že používaný programovací jazyk (dejme tomu C) je pro potřeby aplikace v hodinkách zbytečně silný a jeho bohaté vyjadřovací schopnosti často vedou k chybám v kódu.
Nabízí se otázka, zda by bylo možné aplikaci pro hodinky modelovat ve specializovaném modelovacím jazyce, pokud možno vizuálně, a neprogramovat ji ve zbytečně silném jazyce. Model by obsahoval prvky jako jsou tlačítka, displej, stavy, proměnné atp., a současně by definoval jejich vlastnosti a vzájemné interakce. Z modelu by se pak vygeneroval kód do obecnějšího jazyka. Na následujícím obrázku je ukázka takového modelu2) . V tomto případě se jedná o model stopek v hodinkách.
Modré obdélníky odpovídají stavům hodinek, šedé válečky tlačítkům, žlutá A jsou symboly pro akce a zelené rámečky představují displej. Bílé rámečky reprezentují paměťová místa, tedy proměnné. Jednotlivé prvky jsou propojeny spojnicemi, jejichž význam je dán propojovanými prvky a stylem čáry. Spojnice mezi stavy odpovídá stavovému přechodu, zatímco spojnice mezi tlačítkem a přechodem představuje spouštěcí událost. Spojnice mezi žlutým A a proměnnými definují operaci prováděnou akcí. Na spodní hraně obrázku lze z modelu vyčíst, že akce, která odpovídá zastavení stopek, čte systémový čas z proměnné sysTime, odečítá od něj hodnotu přečtenou z proměnné startTime a výsledek ukládá do proměnné stopTime.
Pozn.: Černé kolečko symbolizuje start činnosti modulu (tzv. počáteční pseudostav), černé kolečko s bílým prstencem symbolizuje konec činnosti (tzv. koncový pseudostav).
Uvedený model můžeme interpretovat takto: stopky se po aktivaci nacházejí ve stavu Stopped. Stiskem tlačítka Down se vynuluje počítadlo stopTime, jelikož se mu přiřadí rozdíl hodnot systémového času sysTime (stopTime = sysTime - sysTime). Stiskem tlačítka Up se přejde do stavu Running, přičemž se do proměnné startTime nastaví rozdíl sysTime - stopTime. Opětovným stiskem tlačítka Up se přejde zpět do stavu Stopped, přičemž do proměnné stopTime se uloží rozdíl sysTime - startTime. Jak lze snadno nahlédnout, uvedené aritmetické operace vedou k akumulaci naměřených intervalů v proměnné stopTime. Stisk tlačítka Mode vede k ukončení činnosti stopek. Displej ve stavu Stopped ukazuje hodnotu stopTime v sekundách, čili naměřený čas. Ve stavu Running pak displej zobrazuje rozdíl mezi systémovým (aktuálním) časem a časem spuštění stopek (startTime).
Pro každý modul v hodinkách (např. světový čas) lze namalovat podobný model. Budou v něm figurovat prvky jako tlačítka, akce, přechody, stavy, proměnné, display a další. Propojování prvků mezi sebou a jejich vlastnosti se řídí pravidly. Není možné například propojit stav a tlačítko spojnicí stavového přechodu. Touto spojnicí lze propojit pouze dva stavy. Souhrn těchto pravidel tvoří gramatiku doménového jazyka a zveme ji metamodel. Metamodel je svou povahou také DSL sloužící k modelování jiných DSL.
Nabízí se přirozeně otázka, na kolik vlastně DSL zvyšují produktivitu? Podle výzkumu z roku 2002 3) vede zavedení DSL k rapidnímu zvýšení produktivity. Porovnání nabízí následující tabulka, ze které lze nahlédnout, jak zavedení jednotlivých programovacích jazyků zvýšilo produktivitu.
Jazyk | Počet nových vlastností produktu implementovaných v daném čase (Normalizováno k Assembleru) |
Assembler | 1 |
Fortran | 4,5 |
Basic | 5 |
C++ (UML) | 6 |
Java (UML) | 6 |
Domain-Specific | 40 |
Z uvedené tabulky vyplývá, že zavedení klasických programovacích jazyků zvýšilo produktivitu pouze nepatrně. Zakopaný pes je v nízké úrovni abstrakce prvků (concepts) uvedených jazyků. Jinak řečeno, tyto prvky jsou svou povahou velmi vzdáleny od objektů z modelované oblasti. Vráťme se k příkladu s hodinkami. Koncept tlačítka je v našem DSL reprezentován jediným symbolem, přičemž v Javě by mu odpovídal kód o mnoha řádkách, o Assembleru nemluvě. Schéma celého aparátu stopek je složeno z řádově desítky objektů.
Kde aplikovat?
Lze snadno a oprávněně namítnout, že stručnost zápisu modelu je přímým důsledkem designu DSL, který byl ušit na míru úzké oblasti výroby digitálních hodinek. Vývoj takového jazyka jistě něco stojí a není vůbec jisté, že se vyplatí. Ano, DSL nelze použít všude a za všech okolností. K tomu, aby jeho vývoj a použití vedly k významnému zvýšení produktivity, je zapotřebí důkladné analýzy a především - schopných specialistů z dané oblasti, kteří mají, pokud možno, zkušenosti s návrhem DSL. Trošku začarovaný kruh. Nicméně zhruba řečeno, uvažovat o adopci DSL má smysl tehdy, provádí-li se opakovaně stejné vývojové činnosti, které vyžadují úzkou specializaci.
V příštím blogu se budu podrobněji věnovat modelování v DSL (DSM).
Reference:
1) Domain-Specific Modeling: Enabling full code generation, Juha-Pekka Tolvanen, OOP2009, Munich
2) Software Productivity Research & Capers Jones, 2002
3) Model hodinek: http://www.methodsandtools.com/archive/archive.php?id=50
No comments:
Post a Comment