Papers we love: Language Hacking in a Live Programming Environment

Deze week wil ik een toffe showcase laten zien. Het is niet echt een paper in de traditionele vorm, maar meer een interactieve demonstratie van een project wat vorig jaar op de LIVE 2016 is gepresenteerd. Wat ontzettend tof is aan deze showcase is dat hij geïnspireerd is op, onder andere, de ideeën van Brett Victor. Mocht je nog niets van deze man hebben gehoord, bekijk dan ook eens een van zijn fascinerende talks  of lees een van zijn essays.

De paper gaat over Ohm, een tool / libray die het bouwen van parsers, compilers en dergelijke gemakkelijker moet maken. Niet een standaard onderwerp, maar wel heel interessant. In de praktijk kom je dit tegen komen wanneer je bijvoorbeeld aan de slag gaat met DSLs . De typische workflow daar is een cyclus die bestaat uit het definieren van een stukje grammatica van je taal, het testen van deze grammatica op wat demo-, of test input (meestal in de vorm van een abstracte syntax tree), het implementeren van een semantische actie en het valideren of dit ook weer het gewenste resultaat heeft. Zoals je kunt indenken is dit nogal een grote en relatief onhandige cyclus. Er zijn verschillende tools (bijvoorbeeld language workbenches) die je hier in ondersteunen. Ook Ohm probeert dit efficiënter te maken.

In Ohm definieer je de grammatica van een taal zonder daar semantische acties in te embedden. Dit houdt in dat je de taal definitie en de taal interpretatie los koppelt, zodat je gemakkelijker (delen van) een taal kunt hergebruiken. Dit is relevant wanneer je meerdere verwante implementaties wilt realiseren of als je dezelfde grammatica bijvoorbeeld meerdere keren implementeert. In de editor waarin je deze grammatica definieert kun je ook voorbeeld-data ingeven. Deze voorbeelden worden vervolgens realtime tegen de geschreven grammatica aangehouden. Expressies die correct worden geparsed zullen als zodanig worden gemarkeerd en vice versa.

Doordat je de voorbeelden continu tegen de grammatica aan houdt krijg je ook instant feedback op je werk. Je weet direct of je werk zich wel of niet gedraagt zoals je verwacht. Hiermee werk je dus op een soort informele manier die wat overeenkomsten heeft met TDD. Geef enkele voorbeelden op, en je krijgt direct antwoord op de vraag of het parseerbaar is of niet. Bij het debuggen is dit natuurlijk ook een mooi mechanisme om snel en grondig hypotheses te testen.

Wanneer input wordt geparsed zal dit resulteren in een CST. Deze boom is niet op de traditionele manier getekend, maar als een kruising tussen een icicle plot en een flame graph. Bij deze manier van visualiseren is hiërarchie zichtbaar als een hoogteverschil en nesting juist door de breedte van een blokje te bekijken. Onderliggende en mogelijk smallere blokjes zijn kinderen van een grotere, bovenliggend component.

Hieronder kun je een afbeelding zien van de editor waarin alle beschreven onderdelen zichtbaar zijn.

Drie aspecten van Ohm die in mijn ogen zeer goed zijn uitgewerkt zijn, naast de “liveness”, het bekijken van parse failures en de zoom functionaliteit. De parse failures worden op een soort platgeslagen manier gevisualiseerd. Hierbij kun je stap voor stap zien welke regels er zijn geprobeerd en wanneer de match faalde en de parser dus de regel afbrak. Doordat je dit in een oogopslag kunt zien heb je iets dat de auteurs abstracting over time noemen — je kunt zelf bepalen welk moment van de uitvoer je in detail wilt bekijken. Zonder dat je iets als breakpoints hoeft te plaatsen.

Het tweede is de zoom functionaliteit. In plaats van dat je altijd begint bij je start rule, de regel (of symbool) dat het begin van je programma aanwijst, kun je een willekeurige (deel)expressie aanwijzen en hier op inzoomen. De grammatica wordt dan gereduceerd naar de selectie en alles wat daar onder hangt. Hiermee kun je dus inzoomen op een specifiek onderdeel om zo bijvoorbeeld te focussen op het toevoegen van een specifiek stukje functionaliteit. Dit werkt, in combinatie met de voorbeelden en het analyseren van parse failures, super efficiënt en eenvoudig.

Het aller mooiste is daarnaast misschien wel dat je het gewoon online kunt proberen. Als je met je browser naar de Ohm editor gaat kun je direct zien waar ik het over heb. Je kunt hier het voorbeeld uitbreiden, spelen met expressies of de CST inspecteren. Een laagdrempeligere manier van kennismaken is bijna niet mogelijk.

Natuurlijk zijn er ook wel verbeteringen mogelijk voor Ohm. Sowieso is het een losse library, wat zaken als editor integratie e.d. wel mogelijk maakt, maar niet direct geeft. Distributie als (bijvoorbeeld) een IntelliJ plugin biedt voordelen die je als JavaScript library niet direct kunt realiseren. Daarnaast is de huidige UI heel erg gericht op relatief kleine expressies en een kleine grammatica. De UI zoals deze nu is ‘schaalt’ niet echt mee. Wel wordt er een voorstel gedaan voor een andere manier van visualiseren die dit deels oplost, dus het is wel op de radar in ieder geval. Als laatste zou ik het ook wel tof vinden als de examples die je maakt tijdens het live coding ook automatisch aan een test suite kunnen worden toegevoegd. Wanneer dat gebeurd weet je zeker dat je de voorbeelden ook structureel blijft testen en dus ook automatisch bent gewaarborgd tegen regressies.

Kortom, wat mij betreft is dit een hele gave tool. Probeer het eens uit door naar de online editor te gaan! Kijk daarnaast ook eens of je in je eigen context en domein kansen ziet om de feedback loop significant te verkleinen. Ik begrijp dat dit niet op dezelfde manier kan als hier met grammatica gebeurd, maar wellicht kun je een mooie parallel vinden.


Over deze papers we love: binnen Sogyo hebben we de traditie dat we maandelijks een nieuwsbrief rondsturen. De nieuwsbrief gaat veel over interne feitjes, echter sinds februari 2015 verzorgd Kevin van der Vlist het topic: papers we love. Hij deelt met ons papers die interessant zijn om te lezen en ons kunnen inspireren. De topic is uitgegroeid tot een mooie verzameling die we ook graag hier willen delen.