Ik geloof sterk in de opkomst van talen voor een speciek domein, ook wel bekend als domein specifieke talen

afgekort: DSL (domain specific language in het Engels). Het grootste bewijs hiervoor is de sterke opkomst van XML.
Waarom? Daarvoor moet ik eerst even kort iets filosoferen wat een programmeertaal nu eigenlijk is. Misschien komt dit stukje wat simplistisch over en denk je 'duh, dat weet ik wel', maar het is wel goed om er eens bij stil te staan. Gewoon doorlezen dus

.
Waarom gebruiken we programmeertalen? Waarom zijn er zoveel verschillende programmeertalen? Waarom gebruikt een programmeur vaak verschillende programmeertalen, terwijl hij in de het dagelijks leven meestal maar 1 taal spreekt (Nederlands in ons geval

)?
Programmeertalen zijn er om een computer op een prettige manier te instrueren. Een computer spreekt in principe maar 1 'taal'. Deze taal is gebaseerd op de architectuur van een computer en wordt 'leesbaar' gemaakt in de vorm van assembly. Assembly is een taal die volledig gericht is op de architectuur van de computer: registers, data, eenvoudige rekenkundige instructies, sprong-instructie enzovoorts. Als je een computer wilt vertellen wat hij moet doen, ligt het voor de hand om dit in de taal van de computer te doen. Als je een Fransman iets wijs wilt maken, moet je dat immers ook in het Frans doen. Maar ja, Frans is niet
jouw taal en daarom is het in vrijwel alle situaties erg lastig om in je in het Frans uit te drukken. Veel liever zou je gewoon Nederlands praten. Het is daarom wellicht effectiever om een tolk in te schakelen en deze jouw Nederlandse boodschap te laten vertalen.
Dit is te vergelijken met de functie van een compiler. Een compiler zet een programma in bepaalde taal (de source taal) om in een equivalent programma in een andere taal (de target taal). Vaak is de source taal op dit moment een imperatieve taal zoals C, C++, C#, Java, Pascal enz. De target taal is vaak assembly.
Programmeertalen zijn ontworpen om jezelf prettig uit te kunnen drukken. Je wilt je probleem zo compact en duidelijk mogelijk omschrijven en programmeertalen trachten deze functionaliteit te bieden aan een programmeur. Problemen verschillen echter sterk: een administratie applicatie is iets heel anders dan een C# compiler en een dynamische website is iets heel anders dan routeplanner.
Daarom zijn er verschillende paradigma's. Het imperatieve paradigma is op dit moment voor 'normale' applicaties nog een zware monopolist. Het imperatieve paradigma is in feite een beetje een abstractie van de architectuur van de moderne computer: imperatief programmeren is sterk gebaseerd op de architectuur van de computer, maar maakt alles toch wat prettiger dan assembly. Imperatief object georienteerd programmeren abstraheert weer een beetje verder, maar is nog steeds sterk gebaseerd op de 'taal' van de computer. Alle 'belangrijke' talen zoals C++, C#, Java, Delphi, PHP verschillen niet bepaald fundamenteel: de verschillen zitten met name in details (of zelfs libraries) en niet bepaald in fundamentele verschillen in uitdrukkingsmogelijkheid.
Er zijn echter ook fundamenteel andere paradigma's. Deze paradigma's worden vaak verzameld onder de noemer 'declaratief'. Declarativiteit is een beetje een vervelende term, maar tegenwoordig wordt er vaak mee bedoeld dat je iets niet uitdrukt in de architectuur van de computer. Functioneel programmeren is hier een voorbeeld van. Bij functioneel programmeren is alles (echt alles!) een functie. Sommige zaken kan je hierin erg prettig en compact uitdrukken, andere zaken (imho) weer een stuk minder

.
Vergelijk het eens met de echte wereld: de Nederlandse taal zou je een general purpose language kunnen noemen. Nederlands kan je in principe wel gebruiken om alles uit te drukken. Java, C, C++, C# etc zijn ook general purpose languages: je kan ze voor alle doeleinden gebruiken. Haskell en Clean (functionele talen) zijn in feite eigenlijk ook nog wel een soort general purpose languages: ze bieden een fundamenteel andere manier om je uit te drukken, maar in principe kan je er alles
aardig goed in uit drukken (let op dat ik de nadruk leg op 'aardig goed' omdat heel veel talen sowieso Turing compleet zijn, wat echter niet wil zeggen dat je iets ook prettig kunt uitdrukken).
SQL en XSLT zijn heel anders: dit zijn duidelijk geen general purpose languages, maar talen voor een specifiek domein. DSLs dus. SQL is uiteraard een taal om queries in te schrijven over een database. XSLT is een taal om transformaties te beschrijven op XML. Beide talen richten zich sterk op problemen in een bepaald domein en daarom kan je problemen in deze domeinen erg prettig in deze talen uitdrukken. XSLT is op dit punt toch nog een beetje anders dan XSLT: in SQL beschrijf je eigenlijk slechts vrij kleine expressies in relationele algebra en daarom noem ik het ook weleens een 'expressie taal'. XSLT is behoorlijk anders: een XSL Transformatie heeft weinig weg van een expressie zoals bijvoorbeeld een numerieke expressie of een expressie in de relationele algebra. XSLT speelt daarom een vrij bijzondere rol. Het is namelijk de eerste declaratieve taal (waarbij ik SQL dus negeer) die gebruikt wordt door een groot publiek: gewone programmeurs ('arbeiders', absoluut niet neerbuigend bedoeld), niet alleen onderzoekers of zeer hoog opgeleide programmeurs.
Terug naar mijn voorbeeld uit de echte wereld: Nederlands kan je dus voor alle doeleinden gebruiken, maar het is lang niet de meest geschikte taal voor alle doeleinden. Niet voor niets zijn er verkeersborden met tekens (in plaats van een omschrijving in het Nederlands) en niet voor niets gebruiken we 22:45 om de tijd aan te geven ipv twee en twintig uur vijf en veertig. Bij het uitprogrammeren van problemen is dit precies zo: een database query omschrijf je het liefst in een taal die zich speciaal richt op dit domein. SQL dus bijvoorbeeld. Een transformatie op een XML document ga je het liefst niet uitprogrammeren in Java met behulp van een DOM, maar beschrijf je in XSLT.
Ik denk dat je in de toekomst steeds meer talen zult zien die zich richten op hele specifieke domeinen. Het wordt namelijk steeds lastiger om je op een compacte manier uit te drukken in een imperatieve taal: applicaties worden steeds groter en de correctheid en de structuur van zo'n applicatie is steeds lastiger in te zien. De enige manier om dit te verbeteren is om talen te ontwikkelen voor een specifiek domein. Talen voor userinterfaces (XUL), talen voor transformaties (XSLT, Stratego), talen voor queries (XPath. XQuery, SQL) enzovoorts. De toepassingen waar echt domein specifieke talen voor nodig zijn kan ik ook niet allemaal voorzien, dus je mag de lijst zelf aanvullen met goede voorbeelden

.
Het is misschien een vreemde sprong, maar XML is het levende bewijs van mijn bewering dat domein specfieke talen een belangrijke rol gaan spelen. Waarom?
XML is namelijk in feite niet echt nieuw. XML valt te formaliseren via een formalisme voor boom-achige talen: 'regular tree languages'. Waarom? Vrijwel alle programmeertalen worden beschrijven met behulp van een grammatica. Deze grammatica is vrijwel altijd een context-vrije grammatica. Allemaal iets om je echt even flink in te verdiepen en dus niet in een paar regels uit te leggen, maar het komt er op neer dat alle programmeertalen in feite een
concrete syntax zijn voor boom-structuur: een abstract syntax tree. Deze abstract syntax tree is niets anders dan een regular tree in een bepaalde regular tree language.
Een klein voorbeeldje: 4 + 5 * 6 is een rekenkundige expressie. Een compiler werkt intern niet met de string '4 + 5 * 6', maar zet dit om naar een boom-structuur. Deze omzetting wordt uitgevoerd door een parser. Een parser zet een string in een bepaalde taal om naar een boom-structuur. Deze omzetting wordt gedaan aan de hand van de grammatica voor deze taal. De boom voor 4 + 5 * 6 zou er zo uit kunnen zien:
code:
1
2
3
4
5
6
7
8
9
| add
|
----- Int: 4
|
|---- multiply
|
----- Int: 5
|
----- Int: 6 |
De grammatica voor dergelijke rekenkundige expressies zou er zo uit kunnen zijn:
code:
1
2
| add: expression "+" expression -> expression
multiply: expression "*" expression -> expression |
(waarbij er elders nog aangegeven moet zijn dat vermenigvulding een grotere prioriteit heeft dan optelling).
Laat ik nu eens deze boom anders gaan schrijven:
code:
1
2
3
4
5
| add
Int: 4
multiply
Int: 5
Int: 6 |
en nog een keer anders:
code:
1
2
3
4
5
| <add>
<Int> 4
<multiply>
<Int> 5
<Int> 6 |
en nog een keer anders:
code:
1
2
3
4
5
6
7
| <add>
<int> 4 </int>
<multiply>
<int> 5 </int>
<int> 6 </int>
</multiply>
</add> |
Hum.... wachts eens.... dat is XML!
Als je op deze manier tegen XML aankijkt, is XML in feite een afsnij-route. XML slaat de hele
concrete syntax over en begint gewoon bij de abstracte syntax (de voordelen hiervan zijn niet het onderwerp van dit topic, dus daar zal ik niet op in gaan...). Elke XML structuur die je ontwerpt is daaromte vergelijken met het ontwerpen van een 'echte' taal. Je ontwerpt een taal in de boom-vorm en je zou daar later nog best een concrete syntax voor kunnen verzinnen (wat met sommige XML talen ook gebeurt).
XML is naar mijn mening voor een groot deel zo populair geworden omdat je er heel gemakkelijk een domein specifieke taal (DSL !!) in kunt maken. Veel XML formaten zijn puur gericht op data, maar is er geen enkele reden waarom je talen voor data echt anders zou moeten behandelen.
XML is vanwege zijn verbositeit echter niet echt geschikt om in te programmeren. Dit is vaak een punt van kritiek op XSLT, terwijl XSLT eigenlijk nog maar voor een klein deel echt de XML aanpak aanhoudt (XPath heeft geen XML syntax). XML is daarom slechts een schets van de mogelijkheden in de toekomst. Het wordt namelijk dankzij allerlei tools en talen steeds makkelijker om eigen 'echte' talen te ontwikkelen. Zodra dit zo weinig moeite kost dat je echt grote voordelen krijgt bij het ontwerpen van een domein specifieke taal, zal er een ware explosie ontstaan van het gebruik van domein specifieke talen, zoals je ook een explosie gezien hebt in het gebruik van XML als uitwissel-formaat tussen applicaties.
Hier zie je code-generatie terug. De voorspelling dat DSLs een belangrijke rol zullen gaan spelen, staat in feite gelijk aan de voorspelling dat code generatie een belangrijke rol zal gaan spelen. DSLs moeten namelijk uiteindelijk toch uitgevoerd worden op een computer en hier komt code-generatie naar voren. DSLs zullen geimplementeerd worden door middel van een vrij eenvoudige compiler die een DSL vertaalt in een imperatieve taal: Java, C++, C bijvoorbeeld.
De kern van dit hele verhaal is dat je in een DSL gaat uitdrukken
wat je probleem is in een specifiek domein. De compiler/code generator zorgt ervoor dat dit 'wat' vertaalt wordt in een 'hoe': De specificatie van wat het probleem is, wordt vertaald in een specificatie van hoe dit probleem moet worden uitgevoerd.
De generator van Otis, die je vast langs hebt zien komen, is een aardig voorbeeld: de specificatie van het probleem zit daar in de database: specificaties van tabellen in de database. Hij had daar ook een domein specifieke taaltje voor kunnen ontwerpen (of dat nu in abstracte syntax (XML) of concrete syntax is (wellicht SQL CREATES)), waarbij de vergelijking nog beter op zou gaan. Uit de specificatie genereert hij enorme smakken code. Deze code valt in een heel specifiek domein: communicatie met een (remote) database vanuit een OO-taal. Code generatie bespaart je hier enorm veel werk, omdat de 'compiler' van Otis weet hoe de specificatie vertaalt moet worden in een implementatie.
Zo. Nu vind ik dat ik wel weer genoeg heb getikt

. Ik hoop dat ik je heb kunnen boeien tot deze afsluiting

.