Monads

English Translation
Zoals op dit blog te zien is experimenteer ik met Scala. Dit is een zgn. “mixed-paradigm”-programmeertaal: je kunt er op Java-achtige manier object-georiënteerd mee programmeren, maar ook functioneel. Ik kom uit de OOP (Object Oriented Programming) hoek, en dus is het functionele deel wel even wennen. De laatste tijd ben ik me ook een beetje aan het verdiepen in Haskell. Ik heb niet de ambitie om de focus echt daar naartoe te verleggen, maar Haskell is puur functioneel, en smokkelen is er dus niet bij. Ook in de scalawereld loop je snel tegen Monads en zo op, maar bij Haskell kun je er niet omheen. Ik hoop er dus een betere Scala-programmeur van te worden.

Ik heb een boek gekocht over Haskell, Learn you a Haskell for Great Good, en al lezende, ook in wat andere bronnen, heb ik me een beeld opgebouwd van wat Monads zijn, en waar ze goed voor zijn. Een weergave van dat door mij opgebouwde beeld vind je hier: Monads en zo.

Ik hoop dat het interessant is voor andere programmeurs, met ambitie in de richting van functioneel programmeren. Zie ook: Wikipedia Monads.

Functioneel programmeren

Een zeer summiere uitleg van FP:
Functioneel programmeren is zeker niet nieuw (stamt uit de 60-er jaren), maar is altijd een beetje een niche-activiteit geweest. De laatste tijd wint het aan populariteit, vooral doordat het een alternatieve aanpak biedt bij concurrent- en multicore-programmatuur. In de tijd van Big Data wordt dat steeds belangrijker.

Klassiek wordt bij multithreading gebruik gemaakt van allerlei locking- en transactie-mechanismen (manieren om op elkaar te wachten bij het gebruik van “shared state”, en als het toch misloopt de boel terug te kunnen draaien).

Bij functioneel programmeren wordt shared state vermeden. Zelfs wordt soms het gebruik van veranderlijke variabelen totaal vermeden. Een variabele is dan in feite een constante: eenmaal een waarde altijd die waarde. Natuurlijk verandert er wel eens wat, maar dan krijg je een nieuwe versie, geen veranderde variabele. (Daardoor kunnen die nieuwe versies intern heel economisch ontstaan: het programma weet dat iets niet zal veranderen en kan dus een “kopie” opslaan in termen van de oude versie met een bepaalde verandering. De berekening wordt “lazy” uitgesteld.)

Klassieke controlestructuren worden vermeden en vaak vervangen door recursie. Een functie is referentieel transparant: als je weet wat erin gaat komt er altijd hetzelfde uit en kun je de functie ook vervangen door het resultaat. Er zijn geen globale zijeffecten. Assignment (tijdelijke toekenning) wordt daarbij vervangen door definities. De functies zijn vaak lui (lazy): er wordt pas gerekend als er om een resultaat wordt gevraagd. Zo zijn ook oneindige collecties mogelijk, (positieve gehele getallen: [1 ..]), want pas als het honderdste element wordt gevraagd wordt dat berekend. Wat erin gaat bij een functie (de argumenten) zijn niet alleen waarden, maar ook weer andere functies. Een soort van Dependency-Injection op functieniveau.

Bij OOP ligt de nadruk op het bouwen van eigen datastructuren. Functionele talen hebben vaak zeer uitgebreide bibliotheken, gericht op geöptimaliseerde standaard-gegevensstructuren. Veel datastructuren zijn Monads (een wiskundig concept uit de groepentheorie) of zwakkere versies daarvan, waardoor er voor veel algoritmen een generieke aanpak kan worden toegepast.

Het zal duidelijk zijn dat het voor een programmeur een totaal andere manier van denken vereist, maar FP heeft ook kanten die het gemakkelijker maakt. Vooral het ontbreken van zijeffecten maakt dat je minder snel voor onverwachte verrassingen komt te staan en dat er gemakkelijker, op bijna wiskundige wijze over een programma kan worden geredeneerd.