Doufám, že vás v mém posledním postu moc nevystrašilo slovní spojení "Domain-Specific Language". Je to jen další buzzword: zní to sofistikovaně, ale ve skutečnosti to není nic nového. Laskavý čtenář, kterému rostou víc vousy než vlasy, si možná vzpomene na minijazyky v unixu, což není nic jiného než DSL - malý jazyk vymyšlený pro konkrétní účel.
Dnes se DSL nejčastěji objevují ve formě konfiguračních souborů. Například *.hbm.xml soubory v NHibernate jsou zapsány jazykem speciálně vytvořeným pro problémovou oblast (=doménu), kterou je v tomto případě mapování mezi databází a objekty. Nebo obyčejný web.config v asp.net aplikaci: To je jazyk specifický pro konfiguraci .NET website, kde je nutné určit které moduly a handlery budou pro který typ souboru použity:-) Takže s nějakým DSL se setkal každý programátor, jen o tom možná neuvažoval jako o DSL.
Doporučuju vám tuto prezentaci, kde Martin Fowler vysvětluje, co si představuje pod pojmem DSL. Všimněte si, že říká že hranice co už je DSL a co ještě není je neostrá. Dokonce i C# nebo java kód může být chápán jako DSL, kde forma zápisu je shodná s programovacím prostředím. V takovém případě se jedná o interní DSL, který lze přímo spustit.
Oproti tomu externí DSL jazyky mají svůj vlastní způsob zápisu, nezávislý na existujících programovacích jazycích. To přináší větší svobodu v definici syntaxe jazyka, na druhou stranu musíme kód nějak parsovat a interpretovat sami. To je natolik složité, že ve většině případů by komplexita parseru a generátoru převážila nad zisky z používání DSL jazyka, což je mimochodem důvod, proč mají tvůrci dnešních DSL tak rádi XML, XSD a XSLT. Další nemalé úsilí by bylo zapotřebí k tomu, aby se "user experience" při používání DSL jazyka přiblížila moderním IDE: Kdo jednou zkusil intellisense ve Visual Studiu a průběžnou analýzu kódu s ReSharperem, těžko se bude chtít vracet k plaintextu.
Když už máme náš nový jazyk definovaný a umíme ho parsovat, je nutné se rozhodnout jak ho budeme interpretovat. Můžeme z DSL jazyka generovat zdrojové kódy v jiných (existujících) jazycích, kompilovat je a distribuovat náš program jako binární knihovny. Druhou variantou je napsat "framework", který bude náš DSL kód interpretovat za běhu a distribuovat tento framework s výchozí podobou DSL kódů, které si koncový klient může upravit podle svého. Typickým příkladem prvního přístupu jsou programy pro modelování v UML, v druhém případě pak konfigurační soubory nebo skriptovací jazyky.
Generování kódu nám jako autorům programu dává do rukou mocnou techniku: Možnost následných úprav vygenerovaného kódu v místě různých "extension points", jako jsou partial třídy nebo double-derived pattern (vygenerujeme base třídu s virtuálními metodami a vlastnostmi a prázdného partial potomka). Díky tomu náš DSL jazyk nemusí řešit všechny krajní varianty. Když to obrátíme můžeme říct, že pokud se rozhodnete váš DSL interpretovat až za běhu, musíte vaše řešení zcela popsat pomocí DSL - včetně všech výjimek a minoritních úkazů. Dostáváte se tak do "customizační pasti", kdy musíte napsat kompletní framework dřív, než budete moci váš DSL použít. Generovat kód je jednodušší, protože se stačí zaměřit na bežné jevy a speciální případy ošetřit v C# nebo jiném vhodném jazyce. Postupně můžeme přidávat počet situací, které jsou v našem DSL řešeny, nebo dokonce můžeme časem implementovat framework pro interpretaci za běhu, ale nebrání nám to začít v malém.
A nyní, milé děti, můžeme plně ocenit sílu language workbenches jako je DSL Tools pro Visual Studio: Jsou to externí jazyky, kde máme syntaxi plně pod kontrolou, máme k disposici parser a generátor, prvotřídní integraci do vývojového prostředí, a navíc grafický editor s předpřipraveným systémem validace modelu, který můžeme upravovat dle libosti. Programátorský Eden. Jediné co chybí je standardní způsob slučování více modelů do jednoho, ale to lze poměrně jednoduše obejít. O tom ale jindy.
Diky za zajimave informace