Já jsem DSL, těší mne
Ne, nebude řeč o internetové konektivitě ani o Damn Small Linuxu, nýbrž o tzv. Domain-Specific Language. Domain-Specific Language, který je často zkracován na DSL, se spolu s webem 2.0 a AJAXem řadí mezi letošní hitovky, takže je dosti možné, že jste o něm již slyšeli.
Co přesně je Domain Specific Language? Wikipedie praví, že se jedná o jazyk navržený a určený k plnění určitého specifického úkolu. V praxi se může jednat například o jakýkoliv framework či sestavovací systém. V DSL lze také velmi dobře psát konfigurační soubory.
Článek je silně inspirovaný prezentací Martina Fowlera a Neala Forda o jazykově orientovaném programování. Veškeré ukázky v článku jsou z této prezentace přejaty.
Proč používat DSL?
- Čitelnější pro člověka
- Umožňuje použít konstrukce programovacího jazyka
- Rychlejší parsování (minimálně v případě interního DSL)
- Je in ;)
Jazykově orientované programování: stromečky vs. jazykový popis
Posledních několik desetiletí v programování je ve znamení stromového popisu – třeba takové XML je toho živým dokladem. Lidský mozek však uvažuje jiným způsobem, nikoliv stromečky, ale jazykem. Jak mluvíme, tak také myslíme, proto aby pro nás byl programovací jazyk co nejpochopitelnější, měl by být co nejpodobnější lidské řeči.
Klíčkovým faktorem pro jazykový popis je kontext, který je u DSL narozdíl od API implicitní.
Popis v API:
Coffee latte = new Coffee(Size.VENTI); latte.setFatContent(FatContent.NON_FAT); latte.setWhip(Whip.NONE); latte.setFoam(Foam.NONE); latte.setTemperature(Temp.EXTRA_HOT); latte.setStrength(5);
Totéž vyjádřeno v DSL:
Venti half-caf, non-fat, extra hot, no foam, no whip latte
Typy DSL
Existují dva základní typy DSL – interní a externí. Interní DSL je nadstavba nad určitým jazykem, je jím vyhodnocována, není tedy třeba psát žádný parser. Velkou výhodou je, že jsou k dispozici veškeré možnosti, které má k dispozici „mateřský“ jazyk.
Externím DSL naproti tomu musíme parser napsat my. To je jistě mnohem náročnější, nemůžeme také použít možností žádného jiného jazyka, ledaže bychom je tam sami doprogramovali, ale o tom DSL není. Na druhou stranu výhoda je v tom, že není třeba uživatele otravovat se závorkami a uvozovkami.
Kde se DSL používá?
DSL není pouze teze hozená od akademického stolu, již dnes se s ním velmi často setkáváme. Mezi jeho nejpopulárnější příklady lze zařadit webový framework Ruby on Rails a sestavovací systém Rake v Ruby, jejich ekvivalenty Grails a Gant v Groovy, utilitku Capistrano pro deploying railsových aplikací a mnohé další.
DSL v praxi
Ideálními jazyky pro psaní DSL jsou jazyky, které si příliš nepotrpí na různé závorky, středníky, které umožňují více možností zápisu a vůbec jsou syntakticky volnější. Podpora closures je další velkou výhodou. Mezi takovéto jazyky podle Martina Fowlera patří především Ruby a Groovy.
class IpBlock < ActiveRecord::Base validates_presence_of :cidr, :address, :prefix_length validates_numericality_of :prefix_length, :only_integer => true belongs_to :function belongs_to :supernet, :class_name => 'IpBlock', :foreign_key => 'supernet_id' belongs_to :anycast_parent, :class_name => 'IpBlock', :foreign_key => 'parent_id' has_many :anycast_children, :class_name => 'IpBlock', :foreign_key => 'parent_id' before_destroy { |ip_block| IpBlock.destroy_all "nat_id = #{ip_block.id}" } before_destroy do |ip_block| IpBlock.destroy_all "anycast_parent_id = #{ip_block.id}" end ... end
Závěr, aneb ovlivní DSL budoucnost programování?
Vzhledem k tomu, že sám nejen používám, ale také jsem vytvořil několik doménově specifických jazyků pro různé účely, myslím si, že DSL určitě význam mají – jak z hlediska syntaxe, která je jednoduchá tak, že jej může mnohdy může pochopit i laik, tak z hlediska úspory času, která může být opravdu enormní. Napsání skromnějšího interního DSL přitom je práce na několik málo hodin. A co vy, zkoušeli jste si již také nějaký DSL napsat?
Odkazy
- DSL, hudba budoucnosti?
- Prezentace Martina Fowlera a Neala Forda: Language Oriented Programming [video, PDF]
- DSL na Wikipedii