--- name: racket-programmeerstijl description: Gebruik deze skill wanneer je Racket-code voor Hans schrijft, wijzigt, refactort of beoordeelt. Pas de bestaande, eenvoudige en procedurele programmeerstijl toe; voorkom over-engineering en onnodige abstracties. Gebruik deze skill niet voor algemene uitleg over Racket waarbij geen code voor zijn projecten wordt gemaakt of aangepast. --- # Racket-programmeerstijl Gebruik deze stijl wanneer je Racket-code voor Hans schrijft of aanpast. ## Uitgangspunt Het *allerbelangrijkste* uitgangspunt is dat je de programmerstijl van Hans volgt. Als je een zip met een package aangeleverd krijgt via de prompt dan volg je de programmeerstijl die je in de aangeleverde code vindt, als die klopt met deze skill. Wanneer bestaande broncode die geprogrammeerd is door Hans beschikbaar is, heeft de stijl van die broncode voorrang. Sluit daar zo nauw mogelijk op aan. Schrijf eenvoudige, directe en goed leesbare Racket-code. Kies de kleinste oplossing die het huidige probleem netjes oplost. Bouw geen abstraheringslaag voor mogelijk toekomstig gebruik. En maak geen helpers die alleen maar in de weg staan. Dus geen code-bloat. Geen overengineering. Gewoon to the point en helder leesbare code. ## Structuur - Houd modules klein en doelgericht. - Splits functionaliteit alleen af naar een private module wanneer die een duidelijk eigen doel heeft. - Gebruik voor duidelijke secties bij voorkeur commentaar in deze vorm: ```racket ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Supporting functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ``` of, wanneer dat beter bij de module past: ```racket ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Internal state / functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ``` Voor publieke functies: ```racket ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Provided functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ``` - Houd `provide` en `require` eenvoudig en overzichtelijk. - Voeg geen extra framework, wrapperlaag of generieke infrastructuur toe zonder concrete noodzaak. ## Beschrijving van functies Geëxporteerde functies/procedures/classes of functies/procedures/classes die daarvoor duidelijk in aanmerking komen, d.w.z. die die provided zijn of naar verwachting zullen worden, moeten gedocumenteerd worden. Zowel in een module scribble als in de code zelf. In het engels. In de code zelf: minimaal: ```racket ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; goal : ; pre : ; post : ; [result:] ; [internals:] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ``` Als een functie/procedure/class overduidelijk in aanmerking komt voor 'provide' en hij staat er nog niet in. Verzamel dan de lijst en vraag of je ze moet toevoegen. Over het algemeen wil ik de internals van een functie weten. Hoe werkt het en waarom werkt het zo. Beschrijf die in de sectie 'internals'. Internals moet de functionele keten beschrijven met concrete namen van helpers en gegevensstructuren, niet alleen een technisch detail noemen. Duidelijk moet zijn **hoe het werkt** en **waarom het zo werkt**. ### Beschrijving van functies in het algemeen Iedere functie die wordt gedefinieerd, tenzij een lokale helper functie van maximaal 5 regels krijgt in ieder geval één commentregel met: ```racket ;;; (or/c path? #f)) (if (eq? cached-value #f) (let ((value (find-value))) (set! cached-value value) value) cached-value)) ``` Een wat langere maar direct leesbare implementatie heeft de voorkeur boven een kortere oplossing met meerdere nieuwe abstracties. # schrijven van documentatie Schrijf altijd documentatie van een package in de scrbl subdirectory in .scrbl files. Als je de auteur aangeeft hierin gebruik je ```scrbl @author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]] ``` # Schrijven van testgevallen voor modules/packages Een test die alleen werkt vanuit de development directory, op het development-OS of met de lokale shell/environment is geen geldige package-test. ## Racket Package Index / build-service tests Als je tests toevoegt aan een racket module, zet daar dan altijd ```racket ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Tests for module voor. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ``` Behandel de Racket Package Index/build service als een aparte, strikte en onbekende testomgeving. Bij packagecode en tests gelden daarom altijd de volgende regels: - Maak nooit aannames over `current-directory` of de directory van waaruit code of tests worden uitgevoerd. Bepaal testdata en paden expliciet en relocatable, bijvoorbeeld met runtime paths en tijdelijke directories. - Maak nooit impliciete aannames over het besturingssysteem. Vermijd OS-specifieke paden, shells, executables en gedrag, of handel verschillen expliciet per platform af. - Maak tests onafhankelijk van lokale environment state. Benodigde environment variables moeten expliciet en bij voorkeur geïsoleerd worden ingesteld. - Een succesvolle test moet stil en ondubbelzinnig succesvol zijn. Laat geen verwachte foutmeldingen naar de echte stdout/stderr lekken, omdat `raco test --drdr` en de Package Index dergelijke output als een mogelijke test failure kunnen classificeren. - Verwachte foutoutput moet worden gecaptureerd en geassert. - Tests moeten hun eigen tijdelijke state en testbestanden aanmaken en mogen geen bestanden, processen, environment changes of andere state achterlaten. - Test packagewijzigingen waar mogelijk ook in een omgeving die lijkt op: `raco setup --check-pkg-deps` en `raco test --drdr --package `.