Evolutionaire verbeteringen van bestaande hogere programmeertalen zijn veel vruchtbaarder dan een revolutionaire taal. Niels Blomberg illustreert zijn stelling aan de hand van een verbeterde versie van de elementaire ‘lus met variabele’.
In Computable (31 juli 1998) beschrijft Jan Karman de taal K, ‘de taal van de toekomst’. ‘K is ontworpen voor het analyseren van massale aantallen ‘real time’ en historische gegevens – ideaal voor financiële modellering’, aldus Karman. Mij lijkt het meer een niche-taal, sterk in een beperkt aantal toepassingen. Toegegeven, het gaat wel om toepassingen die sterk in de belangstelling staan: datawarehousing en Olap.
Maar veel vruchtbaarder dan een revolutie zijn evolutionaire verbeteringen van de bestaande hogere programmeertalen. In de jaren tachtig werden deze talen herdoopt tot 3GL (derde-generatietaal), om aan te geven dat ze verouderd waren door de komst van de 4GL’s. Inmiddels zijn de rollen omgedraaid. De 4GL’s uit de jaren tachtig (Clipper, DBase) zijn verouderd. De oude 3GL’s daartegen zijn in volle glorie terug als onderdeel van nieuwe gui-talen. Basic vormt (onder de naam VBA) het hart van MS Office; Pascal is terug als onderdeel van Delphi.
De hogere programmeertalen zijn in de loop van de afgelopen decennia evolutionair verbeterd. Toch zijn er nog steeds verbeteringen te definiëren, zelfs in zoiets elementairs als de ‘lus met variabele’, ook wel FOR-loop genoemd. Deze lus-constructie kent diverse gedaanten, die hieronder worden behandeld. Tot slot volgt een geheel verbeterde versie.
De oervorm: de tellende lus
Veel programmeurs denken bij ‘lus met variabele’ uitsluitend aan de tellende lus. De tellende lus komt in veel talen voor. De syntaxis in Basic is:
FOR
De opvolgerlus
De ‘lus met variabele’ van Pascal ziet er als volgt uit:
FOR
Op het eerste gezicht lijkt het een tellende lus met alleen de stapgroottes 1 (TO) en -1 (DOWNTO). Dat is op zich wel juist voor INTEGER’s. Echter de basis van deze ‘lus met variabele’ is niet optellen, maar de functie opvolger (TO) en voorganger (DOWNTO). Behalve REAL’s zijn alle basis-types opvolger-types en dus bruikbaar in de FOR:
FOR my_char:= ‘z’ DOWNTO ‘a’ DO …
De discrete lus
Bij de tellende en de opvolgerlus wordt een nieuwe waarde van de lus-variabele bepaald uit de oude waarde. Bij de discrete lus daartegen worden alle aangenomen waarden opgesomd.
Deze ‘lus met variabele’ komt voor in de ‘command languages’ van bijna alle besturingssystemen. Meest gebruikte toepassing is de opsomming van files, meestal met wild-cards. Een voorbeeld uit MS-DOS:
FOR %i IN (*.bat) DO call %i
Ook programmeertalen ‘bovenop’ SQL kennen vergelijkbare constructies:
FOR row IN (SELECT * FROM
Intermezzo: Sets in Pascal
Pascal kent een type set, dat overeenkomt met het wiskundige begrip verzameling. Een voorbeeld van een set: {1,i,i+3}. Zowel constanten, variabelen als expressies kunnen worden gebruikt.
Daarnaast zijn er intervallen, weergegeven door tweede waarden met daartussen twee punten: {1..i+99}.
Tot slot kunnen sets ook bestaan uit ranges en losse elementen: {1..4,6,8,10}.
De verbeterde ‘lus met variabele’
We definiëren de verbeterde ‘lus met variabele’ als een nieuw commando in Pascal:
FOR
Dit is een discrete lus. De Pascal FOR-loop met ‘TO’ wordt geëmuleerd als
De bovenstaande syntaxis moet worden uitgebreid om de ‘DOWNTO’ (of welke volgorde dan ook) te emuleren. Hierbij grijpen we terug op de selectie- en sorteringsmogelijkheden van het SQL-statement SELECT. Twee voorbeelden:
FOR i in {1..19} ORDER BY -i
FOR i in {1..19} WHERE ODD(i) DO
Het eerste voorbeeld is een emulatie van de ‘DOWNTO’. In het tweede voorbeeld worden alleen de oneven getallen in het interval meegenomen, een emulatie van een tellende lus met stapgrootte 2.
ANY_ORDER
Vaak is de volgorde waarin de lus wordt doorlopen onbelangrijk. Dat kan worden aangegeven met ANY_ORDER. In onderstaand voorbeeld worden de elementen van een array gesommeerd:
sum:=0;
FOR i IN {1..MAX} ANY_ORDER DO sum:=sum+ry[i];
Het gebruik van ANY_ORDER verhoogt de leesbaarheid van de broncode. Daarnaast kan de compiler zelf de optimale volgorde bepalen.
PARALLEL
In het bovenstaande voorbeeld wordt de variabele ‘sum’ gewijzigd, elke keer dat deze de lus doorloopt. Bij lussen waar een dergelijke variabele ontbreekt, is het mogelijk om de commando’s voor de verschillende waardes van de lus-variabele parallel uit te voeren:
FOR i IN {1..MAX} PARALLEL DO ry[i]:=ry[i]+1;
Net als ANY_ORDER verhoogt PARALLEL de leesbaarheid van de broncode. Indien de gebruikte hardware en systeemsoftware parallelle verwerking ondersteunt, is dit tevens een teken voor de compiler om een en ander te parallelliseren.
Verbetering
De verbeterde ‘lus met variabele’ is een combinatie van bestaande concepten: de discrete lus, de SET’s van Pascal en de WHERE en ORDER BY van SQL. Door deze zaken te combineren, ontstaat een ‘lus met variabele’ met de functionaliteit van zowel de opvolgerlus, de discrete lus en (via WHERE) de tellende lus met willekeurige stapgrootte.
ANY_ORDER en PARALLEL zijn min of meer logische uitbreidingen van de ORDER BY.
PARALLEL maakt hogere programmeertalen geschikt voor parallelle hardware.
Drs. C.Blomberg, senior information engineer by Stork Engineers and Contractors (SE&C)