Pieter Edelman
14 September 2017

Er worden voortdurend nieuwe programmeertalen ontwikkeld, maar de meeste voegen te weinig toe of krijgen niet de kritieke massa die nodig is om echt aan te slaan. Zo nu en dan komen er talen bij die wel een serieuze duit in het zakje kunnen doen. Bits&Chips zet er een paar op een rijtje.

Aan programmeertalen is er op de wereld geen gebrek. Met de regelmaat van de klok worden er nieuwe talen en raamwerken gelanceerd om alle problemen met de huidige aanpakken te verhelpen – te ingewikkeld, te veel overhead, niet veilig genoeg, te veel geheugengebruik – of spannende nieuwe concepten uit te werken. Het zit nu eenmaal in de aard van de programmeur om problemen op de meest elegante manier op te willen lossen, en niet per se op de meest pragmatische.

Natuurlijk is niet voor elke nieuwe taal een leven in de spotlights weggelegd. Een volledig nieuw formalisme ontwikkelen, met bijbehorend ecosysteem en bijbehorende bibliotheken, vereist commitment. En programmeurs staan niet te springen om (weer) een nieuwe taal, nieuwe omgeving of nieuw paradigma te omarmen als daar niet duidelijke meerwaarde aan verbonden is. Bovendien mogen er geen zorgen zijn over kosten, beschikbaarheidsgaranties en ondersteuning.

Zo nu en dan komen er talen voorbij die wel tractie krijgen en langzaam aan een zegetocht beginnen. Hieronder hebben we enkele opkomende talen op een rijtje gezet die interessant kunnen zijn voor de Bits&Chips-lezer, dus met een nadruk op systeemtalen – overigens zonder te pretenderen compleet of zelfs maar objectief te zijn. Dus met excuses voor de willekeur: zeven min of meer nieuwe programmeertalen om in de gaten te houden.

Bc05 2017 illustratie 7_programeertalen

Go(lang)

Een groepje Unix- en programmeertaalveteranen bij Google keek een decennium geleden eens goed naar wat vier decennia C had opgeleverd. Ze zagen systeemtalen als C++ en Java: objectgeoriënteerd en krachtig, maar complex in gebruik en soms wel erg onleesbaar. Het alternatief, talen die wel elegant en leesbaar zijn zoals Ruby, Python en Javascript, worden allemaal geïnterpreteerd en hebben nadelen rond performance, type safety en deployment.

 advertorial 

The waves of Agile

Derk-Jan de Grood has created a rich source of knowledge for Agile coaches and leaders. With practical tips to create a learning organization that delivers quality solutions with business value. Order The waves of Agile here.

Ze vroegen zich af: waarom kan een systeemtaal niet elegant zijn? Ze besloten een nieuwe poging te wagen om een C-achtige systeemtaal te maken die de problemen zou adresseren. Een taal die makkelijk te lezen en te schrijven is, met automatisch geheugenbeheer, maar statisch getypet en gecompileerd.

En als ze dan toch aan de slag gingen, waren er nog wel meer problemen. Neem de buildketen van een typisch C++-project: een samenraapsel van compilers, debuggers, preprocessors en testraamwerken, aan elkaar gelijmd met een ingewikkeld buildsysteem dat bijna een programmeertaal op zich is. Afhankelijkheidsbeheer is een verhaal op zich. Daarnaast blijven compileertijden alsmaar oplopen en is een compilerfout ontcijferen soms een complete studie.

Hun taal moest dus ook een heldere, eenduidige toolketen krijgen en een efficiënte compiler. Bovendien moest hij moderne features zoals concurrency ondersteunen. Het eerste resultaat werd in 2009 onthuld als Go. De taal probeert te leren van de ontwikkelingen van de afgelopen decennia, maar haalt de doorgeschoten aanpakken weer terug naar de aarde. Zo is Go objectgeoriënteerd, maar dan zonder een hele overervingshiërarchie (in plaats daarvan worden interfaces gebruikt). Typing is sterk, maar niet per se expliciet; de compiler kan vaak het juiste type uitvogelen aan de hand van waarden of signatuur.

Go zet ook in op geheugenveiligheid, onder meer door automatisch geheugenbeheer via garbage collection. Maar ook bijvoorbeeld door runtime controles van arraytoegang en ontmoediging van low-level geheugentovenarij. Tegelijk is het wel een systeemtaal, waarmee de programmeur mogelijkheden heeft om de geheugenindeling naar zijn hand te zetten.

Daarnaast laat Go zichzelf voorstaan op sterke ingebouwde concurrency-mogelijkheden via zogeheten ‘goroutines’. Dit zijn functies die in een eigen lichtgewicht threadingsysteem worden ondergebracht. Communicatie met lopende goroutines verloopt via expliciete berichten in plaats van gedeeld geheugen.

De meeste programmeurs tonen zich in eerste instantie echter niet zozeer enthousiast over de taal zelf, als wel over de bijbehorende infrastructuur. Projecten hebben een eenduidige directorystructuur en de basistools regelen alles van compilatie tot afhankelijkheidsbeheer en testen. De compiler werkt bovendien razendsnel en produceert behulpzame meldingen.

Een probleem was er wel: omdat ‘Go’ in de praktijk wat lastig is in het taalgebruik en – o ironie – als zoekterm, moest iets beters worden bedacht. Daarom wordt de taal vaak aangeduid als ‘Golang’.

Rust

Rust heeft ook een grote sponsor achter zich: Mozilla, het bedrijf achter de Firefox-webbrowser. De aanleiding voor een eigen programmeertaal was het geheugendilemma waar de browserprogrammeurs vaak mee worstelen: het merendeel van de beveiligingsfouten is terug te voeren op het handmatige geheugenbeheer in C++, maar geheugenveilige talen met garbage collection betalen een te hoge performance-penalty voor gebruik in een webbrowser.

Daarom begonnen ze bij Mozilla te experimenteren met verschillende aanpakken, om daar uiteindelijk een handvol uit te pikken en die glad te polijsten in hun nieuwe taal. Een van de belangrijke overwegingen daarbij was dat checks zo veel mogelijk voor rekening van de compiler moeten komen zodat er geen runtime overhead wordt toegevoegd.

Centraal in Rust staat het eigenaarschapsmodel voor data, waarbij elke variabele altijd een enkele unieke eigenaar heeft. Dit zet een streep door een hele klasse problemen, terwijl de aanpak het toelaat om alle controles al tijdens het compileren te onderscheppen. Als bonus krijgt Rust er met dit mechanisme gratis krachtige concurrency-mogelijkheden bij.

Nadeel is wel dat de taal niet makkelijk te leren is. Uit de praktijk blijkt dat het tijd en moeite vergt om de denkwijze van Rust te doorgronden. ‘Fighthing the borrow checker’ is een veelgehoorde term onder newbees, verwijzend naar de worstelingen met het eigenaarschapsmodel. Menigeen zegt het meerdere keren geprobeerd te hebben voordat de denkwijze uiteindelijk klikte.

Voor syntax en features hebben de ontwerpers geprobeerd zo veel mogelijk slimmigheidjes uit andere talen te lenen. Zo is Rust objectgeoriënteerd zonder overerving, een beetje zoals Go. En net als Go heeft de taal een gestroomlijnde toolketen, heldere foutmeldingen en ook nog een repository voor externe modules. Pluspunt is dat Rust-code makkelijk te combineren is met C en C++. Logisch, aangezien het herschrijven van een hele browser alleen in kleine stapjes kan.

Elixir

Voor Elixir was concurrency niet een van de vele dingen om rekening mee te houden, het is de nummer een bestaansreden van de taal. De manier waarop dat wordt aangepakt, is net als in Go via lichtgewicht processen die expliciet berichten uitwissen. Het achterliggende paradigma is compleet anders: Elixir is een functionele programmeertaal. Dat heeft direct voordelen voor concurrency, want zaken als niet-muteerbare toestanden maken het veel makkelijker om te redeneren over parallelle functies die elk hun eigen ding doen.

Anders dan Go of Rust is Elixir wel een geïnterpreteerde taal. Zeker voor sterk concurrente systemen steekt de performance echter gunstig af. Dat doet de taal door zich te baseren op en aan te sluiten bij Erlang, de functionele taal die ooit is ontwikkeld bij Ericsson om grootschalige telefooncentrales te programmeren. Elixir volgt grotendeels het taalontwerp van Erlang en wordt gedraaid op de Erlang VM, waarmee Elixir-programma’s zeer grote aantallen onafhankelijke processen tegelijk kunnen draaien.

Uiteraard voegt Elixir nog wel het nodige toe aan Erlang. Zo kent Elixir een uitgebreid metaprogrammeersysteem om de taal uit te breiden met nieuwe functionaliteit. Ook worden er allerlei moderne features toegevoegd die het leven van de programmeur makkelijker moeten maken, zoals inline documentatie en testen, een interactieve shell en ook weer een moderne toolketen met onder meer een test- en buildsysteem en een packagemanager.

Kotlin

Nabij de Russische stad Sint-Petersburg, waar softwareontwikkelaar Jetbrains is gevestigd, ligt het eiland Kotlin. De keuze van de Russische programmeurs om hun nieuwe formalisme naar dit eiland te vernoemen, is een subtiele verwijzing naar een andere taal met de naam van een eiland; Kotlin werd ontwikkeld als ‘beter Java’.

Echt veel nieuws brengt Kotlin dan ook niet met zich mee, maar ten opzichte van Java, dat pijnlijk veel typewerk kan vereisen, biedt het een modernere en compactere syntax. Verder past de taal naadloos in het Java-ecosysteem: Kotlin draait op de JVM, gebruikt de standaard buildtools, kan Java-bibliotheken aanroepen en nestelt zich comfortabel in Java-projecten.

De taal was tot voor kort vrij onbekend, maar kreeg eerder dit jaar een boost doordat Google Kotlin volledig omarmde als tweede taal voor Android-ontwikkeling. Erg verrassend is dat achteraf gezien niet. Kotlin is nauw verbonden aan Jetbrains’ primaire product, de Intellij Idea-ontwikkelomgeving. Deze vormt ook de basis voor de Android-ide, en Android houdt Intellij graag te vriend.

Sinds zijn eerste verschijningsvorm in 2011 is de scope van de standaard implementatie nog wat uitgebreid voorbij Java. Er is nu ook een compiler voor native targets en een transpiler naar Javascript. Kotlin abstraheert het target echter niet geheel; programmeurs zullen rekening houden met het target waarvoor ze ontwikkelen.

Python

Oké, eigenlijk hoort Python, een taal die al in 1991 het levenslicht zag, niet thuis op deze lijst. Zeker niet omdat hij wel als mainstream beschouwd kan worden en zeker geen systeemtaal is.

Python heeft echter een hoofdrol opgeëist in een gebied dat razendsnel belangrijker wordt: kunstmatige intelligentie en datawetenschappen. Bijna alle belangrijke raamwerken voor machine learning en deep learning zoals Caffe en Google’s Tensorflow hebben hun primaire interface in Python. Toen Baidu, Facebook en Microsoft met hun eigen raamwerken kwamen, zorgden ze dan ook voor een Python-interface. Ook in de datawetenschappen zingt Python een aardig toontje mee via diverse raamwerken.

Python Notebook

Dat komt omdat wetenschappers van allerhande signatuur – van astro- tot zoölogen – het belang van datasets in hun werk sinds de eeuwwisseling steeds meer zien toenemen. Dankzij de vriendelijke syntax, vergevingsgezinde omgeving, interactieve prompt en uitbreidingsmogelijkheden was Python een goede match voor deze niet-hardcore programmeurs om hun automatiseringsbehoeftes te bevredigen.

Dit leidde tot allerhande extensies, onder meer voor wiskunde, matrixbewerkingen en machine learning. De neurale netten zijn een logisch vervolg. Zeker voor de moderne Silicon Valley-bedrijven, die opensource weer sterk verkiezen boven gesloten aanpakken.

Vandaag de dag is de Python-gereedschapskist fors uitgebreid met allerhande bibliotheken voor visualisatie en data-analyse. Belangrijke troef zijn ook de Notebooks: interactieve documenten met uitvoerbare Python-code, waarmee cases en voorbeelden makkelijk zijn uit te wisselen tussen onderzoekers en ontwikkelaars. Overigens zijn deze onlangs weer losgemaakt uit Python en ook beschikbaar voor andere scriptingtalen zoals Ruby en Julia.

Blockly

Zogeheten ‘visuele programmeertalen’ waarbij programma’s worden gemaakt door bouwblokken met elkaar te verbinden, zijn over het algemeen niet populair. Veel programmeurs beschouwen dit vooral als speelgoed, niet als gereedschap voor serieus werk. En daar zit wel wat in. Blokjes uitzoeken, slepen en configureren is in de regel veel langzamer dan een simpel stukje code typen, om maar te zwijgen over het aanpassen van de structuur.

Blockevly_World

Toch is er ook wat te zeggen voor de visuele aanpak. Zo springt de structuur van het programma direct in het oog, hoeft de programmeur minder uit zijn hoofd te leren omdat functionaliteit op een palet van bouwstenen te kiezen is en is compatibiliteit tussen blokken direct zichtbaar met kleuren of vormen van connectoren. Er zijn dan ook verschillende succesvolle programmeeromgevingen die een deel of het hele programmeerwerk visueel aanpakken – denk aan UML, National Instruments’ Labview, Lego Mindstorms of de Scratch-leeromgeving van het MIT Media Lab.

Blockly is een relatief nieuwe tool van Google om visuele code-editors mee te bouwen. Het gereedschap wordt geleverd als Javascript-bibliotheek die kan worden geïntegreerd in websites en in apps. Standaard zitten er diverse bouwblokken in voor basaal programmeerwerk, maar de taal is gemaakt om te kunnen worden uitgebreid met eigen bouwblokken. Het resultaat van een bouwwerk kan worden geëxporteerd naar Dart, Javascript, Lua, PHP en Python. En ook hier is het mogelijk eigen backends toe te voegen.

Zo kan Blockly bijvoorbeeld op maat worden gesneden voor experimenteerbordjes, met bouwblokken voor de drukknopjes, ledjes en sensoren. Microsoft heeft een programmeeromgeving voor het Micro:bit-bordje online gezet dat inspeelt op de beschikbare sensoren en ledjes. Maar er is ook al iemand bezig met een VHDL-editor gebaseerd op Blockly.

Een voorbeeld is de App Inventor van Google en het MIT Media Lab. Zoals de naam verraadt, zijn hiermee apps voor smartphones te maken, met bouwblokken voor dingen die typisch op deze toestellen te vinden zijn: camera’s, bewegingssensoren, bluetooth, gps, speakers, noem maar op. De tool heeft veel weg van Scratch, eveneens van het MIT, en de relatie tussen de drie – it’s complicated. Maar de volgende versie van Scratch wordt eveneens gebaseerd op Blockly.

Nim

Nim is qua doelstelling wel een beetje vergelijkbaar met Go en Rust: de ontwikkelaars hebben het ook over een moderne geheugenveilige systeemtaal. Nim gebruikt hiervoor wel weer automatisch geheugenbeer, maar claimt desondanks ‘bijna-C-performance’. De troefkaart is om alle trucs rondom garbage collection uit de kast te halen en die ook voor de programmeur te ontsluiten. De garbage collector kan daardoor worden getuned over het hele spectrum van deterministisch en soft realtime gedrag tot aan snelle reference counting.

Ook op andere aspecten positioneert Nim zich als een taal die vooral erg efficiënt is. Een minimale ‘Hello world!’-binary, waar de runtime met garbage collector wordt meegelinkt, weegt bijvoorbeeld slechts veertig kilobyte. De Nim-ontwikkelaars zeggen dat een deel van de efficiëntie komt doordat hun compiler niet direct naar machinecode compileert, maar C als tussenlaag gebruikt. Daardoor kan worden meegelift op alle optimalisaties die de afgelopen decennia zijn doorgevoerd in C-compilers. Overigens is er ook een Javascript-backend aanwezig, met de gedachte dat dezelfde code voor zowel een web-backend als frontend kan worden gebruikt.

Nim is een hoogniveautaal met moderne en efficiënte syntax, die sterk leunt op Python – onder meer het structureren via indentatie wordt gebruikt – en daarnaast inspiratie opdeed bij onder meer Oberon en Pascal. De ontwikkelaars zijn verder grote fans van statische typing. De taal biedt bovendien zaken als metaprogramming-mechanismen en interoperabiliteit met C/C++/Objective C-bibliotheken. En ook bij Nim komt de toolketen met een eigen packagemanager.

Een waarschuwing is wel op haar plaats: de taal en de compiler zijn nog in ontwikkeling, een versie 1.0 is er nog niet en er kunnen compatibiliteitsissues ontstaan. Voor productiewerk is het het beste om nog even te wachten.