Pieter Edelman
16 August 2018

Na bijna negen jaar ontwikkelen is de stabiele 1.0-versie uitgebracht van Julia, een opensource, gecompileerde, garbage-collected, high-level programmeertaal met focus op wiskunde, wetenschap en engineering. Tijd om eens te kijken wat de nieuwkomer allemaal te bieden heeft.

‘Omdat we hebberig zijn’, schreven computerwetenschappers Jeff Bezanson, Stefan Karpinski, Viral Shah en Alan Edelman begin 2012 als antwoord op de vraag waarom ze een nieuwe programmeertaal wilden ontwikkelen – de zoveelste. Allemaal gebruikten ze in hun dagelijkse werk een combinatie van talen en tools om grootschalige wetenschappelijke computervraagstukken door te rekenen. En die voldeden, en ze waren er blij mee, maar ze wilden dus nog meer: een enkele taal die alle voordelen van de andere talen combineert, zonder de nadelen.

Dus stelden ze een ambitieus wensenlijstje op: ‘We willen een opensource taal met liberale licentie. We willen de snelheid van C, met het dynamische karakter van Ruby. We willen een taal die homo-iconisch is met echte macro’s zoals in Lisp, maar die een logische en wiskundige notatie gebruikt, zoals Matlab. We willen iets dat zo algemeen toepasbaar is als Python, zo makkelijk voor statistiek als R, zo natuurlijk voor tekstverwerking als Perl, zo krachtig voor lineaire algebra als Matlab en zo goed in het aan elkaar lijmen van programma’s als shell. Iets dat kinderlijk eenvoudig is om te leren en tegelijkertijd serieuze hackers blij kan maken. We willen dat het interactief is en gecompileerd’, schreef het viertal in een blog.

Daar hield het wensenlijstje zelfs niet op. Programmatuur geschreven in hun ideale taal moet in één ruk door schaalbaar zijn naar duizenden processoren en gpu’s. Installatie en configuratie moeten simpel zijn. Er moet interactie mogelijk zijn met alle software die ooit is geschreven.

Toen kwam de aap uit de mouw: ze waren al zo’n tweeënhalf jaar aan het sleutelen aan zo’n taal, die ze Julia hadden gedoopt. Ze kwamen ermee naar buiten omdat het zo langzaamaan wel tijd was voor de 1.0-release.

Dat was wat optimistisch; pas deze maand was het zover. De taal is nog lang niet uitontwikkeld, maar de fundamenten zijn af en zullen niet meer veranderen, waardoor iedereen er nu echt mee aan de slag kan. Tijd dus om eens een kijkje te nemen.

Meer Matlab dan Python

Als programmeertaal komt Julia in eerste instantie inderdaad over als scriptingtaal. Gebruikers hoeven niet na te denken over geheugenbeheer en types zijn optioneel, code is makkelijk te lezen en er zijn zelfs geen puntkomma’s en curly braces om over te struikelen. Er is bovendien een vriendelijke interactieve omgeving waar gebruikers kunnen spelen met de code.

Schijn bedriegt echter, want de code wordt wel degelijk gecompileerd en draait dan meestal razendsnel – in benchmarks komt Julia erg dicht in de buurt van C. Het duurt wel even voordat Julia-programma’s op gang komen omdat er doorgaans een just-in-time-compiler wordt gebruikt die eerst de machinecode moet genereren (de Julia-gemeenschap lijkt nogal te worstelen met de vraag of het ook mogelijk moet zijn direct naar machinecode te compileren).

Het is duidelijk dat het zwaartepunt van de taal ligt op wiskunde en engineering. Arrays worden bijvoorbeeld benaderd uit het oogpunt van wiskundige vectoren of matrices: ze zijn multidimensionaal en beginnen bij 1, en voor elke normale operator is automatisch een variant beschikbaar die op vectoren werkt. Daarnaast zijn breuken en irrationele getallen first-class citizens in Julia, net als ontbrekende waarden – belangrijk voor statistiek. Enkele belangrijke wiskundige constanten zijn als global beschikbaar en de interactieve omgeving begrijpt Latex-notatie om makkelijker met symbolen te kunnen werken. De taal heeft daardoor meer weg van Matlab of R dan van Python of Ruby.

Dat is ook terug te zien in het ecosysteem. Er is een uitgebreide verzameling wiskundige en wetenschappelijke pakketten beschikbaar, uiteenlopend van datascience en machine learning tot biologie en quantumfysica. De populaire bibliotheken voor visualisatie, en de populaire Jupyter Notebooks, worden volop ondersteund, wat niet gezegd kan worden van bijvoorbeeld gui-toolkits.

Functies zijn belangrijker dan objecten

Waar de taal waarschijnlijk nog het meest afwijkt van de mainstream is de manier waarop hij aankijkt tegen objectoriëntatie. De ontwerpers hebben het paradigma van multiple dispatch hoog in het vaandel, wat inhoudt dat een functie meerdere implementaties kan hebben, voor verschillende typen parameters. De programmeur voegt implementaties toe naargelang dat nodig is.

Dit principe botst met traditionele oo-talen zoals C++ of Java, waarin functies (methodes) onderdeel zijn van het type (de objecten). De Julia-ontwerpers vinden dit vanuit de wiskundige achtergrond onlogisch, want in de wiskunde staan de bewerkingen centraal, niet de datatypes. Vermenigvuldigen moet je bijvoorbeeld net zo goed met irrationele getallen kunnen doen als met hele getallen of fracties, of combinaties daarvan. Een ‘vermenigvuldig’-functie hoort in hun ogen geen onderdeel te zijn van een van die datatypes.

Julia heeft daarom een objectsysteem dat zich richt op datavelden, compleet met constructors en een typehiërarchie. Volgens de makers van de taal past dit eigenlijk bijna altijd wel beter dan de gebruikelijke oo-aanpak. De meningen hierover zijn, uiteraard, verdeeld.

Mee met de trends

Julia is verder een moderne programmeertaal die de belangrijke trends volgt. Zo adopteert de taal gedeeltelijk het idee dat nieuwe variabelen onveranderlijk zijn tenzij anders aangegeven. De interactieve omgeving en packagemanager zijn ingebakken en er zijn uitgebreide metaprogramming-capaciteiten (de voornaamste reden dat er een jit gebruikt moet worden).

Julia besteedt ook uitgebreid aandacht aan mogelijkheden voor parallel en gedistribueerd rekenen. De taal ondersteunt op hoog niveau het principe van coroutines die via kanalen met elkaar communiceren, maar kan ook op lager niveau compileraanwijzingen geven over het automatisch parallelliseren van code, of omgaan met threads. Ook dit is een erfenis van de achtergrond van Julia: met deze mechanismen kunnen programma’s worden verdeeld over de duizenden processoren in supercomputers en worden gedraaid op hardwareversnellers zoals gpu’s.

Aan de andere kant ontbreekt er ook wel het een en ander. De standaard bibliotheek is bijvoorbeeld vrij summier. Julia is niet batteries included en leunt op de packagemanager om ontbrekende functionaliteit in te vullen. Daarmee wordt het succes van de taal afhankelijk van het succes van zijn ecosysteem.

Ook modelleren is een zwak punt. Er zijn wel bibliotheken beschikbaar, maar echt geavanceerde modelleerfaciliteiten ontbreken. Voor de makers is dit ook geen speerpunt.

Waar is Julia goed voor?

De vraag is dus of alle beloften worden waargemaakt die de vier auteurs in 2012 deden. Julia 1.0 komt in elk geval een heel eind en biedt een moderne en makkelijk programmeerbare taal met goede performance en goede mogelijkheden tot uitbreiding. Dankzij het gezonde ecosysteem eromheen kan de taal zich op sommige gebieden meten met Matlab, Numpy, Octave en R.

Maar tegelijk is er weinig te vinden dat aanleiding geeft om de overstap te maken. De performance mag volgens de makers beter zijn dan die van de concurrentie, maar in de praktijk is dat daar zelden een probleem en eventuele bottlenecks zijn doorgaans eenvoudig op te lossen. Ook als algemene programmeertaal blinkt Julia nergens in uit. De multiple dispatch-aanpak is wellicht een interessant alternatief voor traditionele oo, maar wat dat betreft, kan Julia achter in de rij aansluiten. Het is ook de vraag of de manier van werken schaalt naar grote en complexe projecten.

Daarmee lijkt Julia’s rol vooral voorbehouden aan specifieke niches. Wanneer er bijvoorbeeld op grote rekenclusters moet worden gewerkt, zou de nieuwe taal een logische keus kunnen zijn. Maar wie weet. De afgelopen jaren was het nog lastig om Julia echt te gebruiken omdat er nog volop werd gesleuteld aan de basisbeginselen; nu de eerste stabiele versie uit is, kan dat veranderen.