En arrays dan?
Arnout van Kempen over rommelen in een digitale wereld.
Hebben we in COBOL nog samengestelde types, zoals arrays, vectors, hasmaps, matrices, lists en al dat moois? Nou, grotendeels, nee.
Laat ik eerst aangeven waarom je in COBOL al die ingewikkelde structuren niet hebt. Deels natuurlijk omdat COBOL een oude taal is, maar dat is niet helemaal de reden. Talen als Fortran, Lisp, Algol en C zijn ongeveer even oud en daar zit toch al meer complexiteit in de datastructuren dan COBOL kent. Ik denk dat twee redenen veel belangrijker zijn: veel van die complexe structuren zijn simpelweg niet nodig in de wereld waarin COBOL koning is en COBOL nodigt veel meer dan andere talen uit om bestandsopslag te gebruiken.
Als je het gemak ziet waarmee COBOL bestanden gebruikt, vrijwel hetzelfde als intern geheugen, en je bedenkt het gedoe in C om datzelfde te doen, dan zie je waarom ik denk dat bestandsgebruik meer voor de hand ligt in COBOL. Bedenk ook dat COBOL werd ontwikkeld in de tijd dat extern geheugen, via ponskaarten desnoods, oneindig was, terwijl intern geheugen van een mainframe niet groot was. Een van de eerste commercieel succesvolle mainframes van IBM, de 1401, had bijvoorbeeld maximaal (!) 16K aan 6-bits werkgeheugen. Die 6-bits betekenen dat je alleen met hoofdletters kon werken en die 16K betekenen dat je geen grote structuren in het interne geheugen wilt hebben. Dat past simpelweg niet. Dat interne geheugen is eigenlijk pas bij System Z, het mainframe van de afgelopen dertig jaar, serieus groot geworden. Inmiddels rekent IBM in terabytes. Maar de grote commerciële mainframes als S/360, S/370 en zelfs AS/400 werkten met heel veel kleinere interne geheugens. En dus is het logisch om in COBOL niet te zwaar op dat interne geheugen te steunen.
Het andere argument dat ik noemde, is het soort toepassingen dat met COBOL werd gebouwd (en eventueel nog wordt). Administratieve systemen die bijvoorbeeld miljoenen transacties van creditcards moeten ontvangen en verwerken, moeten wel heel snel heel veel kunnen doen, maar de bijbehorende datastructuren zijn niet extreem complex. Je doet één transactie tegelijk, waarbij je data uit een paar bronnen combineert, verwerkt en weer opslaat. Dat moet heel exact en extreem betrouwbaar gebeuren. Mainframes zijn precies daar heel goed in: veel data, heel exact verwerken en extreem betrouwbaar. COBOL past daar bij.
Dat neemt niet weg dat COBOL, zoals veel talen, beschikt over een data-structuur die grote overeenkomsten vertoont met een random toegankelijk bestand: de array, of zoals COBOL ze noemt, tables. En nog meerdimensionaal ook!
De simpelste vorm is de eendimensionale table, bijvoorbeeld deze die sales per maand kan vastleggen:
01 SALES-AMOUNTS.
05 MONTHLY-SALES OCCURS 12 TIMES PIC 9(5)V99.
Als je een omzet van 1200,- wil registreren in februari doe je dat met
MOVE 1200.00 TO MONTHYLY-SALES(2).
Het valt hopelijk op dat COBOL op een menselijke manier telt. Anders dan in veel van C afgeleide talen die, net als een computer intern, beginnen te tellen bij 0, begint COBOL bij 1. Het volgnummer voor februari is dus 2, en niet 1 zoals in C gebruikelijk.
Wat nu als je maandelijkse omzet voor alle drie je regio’s wilt registreren? Dan maken we een meerdimensionale table:
01 SALES-MATRIX.
05 SALES-REGION OCCURS 3 TIMES.
10 MONTHLY-SALES OCCURS 12 TIMES PIC 9(5)V99.
En nu kan je voor regio 1, maand februari, een omzet van 1200,- registreren met
MOVE 1200.00 TO SALES-REGION(1) MONTHLY-SALES(2).
Deze manier van benaderen van gegevens in een table wordt subscripting genoemd. COBOL kent daarnaast ook indexing. Dat ziet er zo uit
01 SALES-AMOUNTS.
05 MONTHLY-SALES OCCURS 12 TIMES PIC 9(5)V99
INDEXED BY SALES-INDEX.
en in de procedure:
SET SALES-INDEX TO 1.
MOVE 1000.00 TO MONTHLY-SALES(SALES-INDEX).
Dat ziet er niet erg spannend uit. Maar nu iets uitgebreider, met wat extra variabelen ook:
WORKING-STORAGE SECTION.
01 TARGET-SALES PIC 9(5)V99 VALUE 1200.00.
01 FOUND PIC 99.
PROCEDURE DIVISION.
SET SALES-INDEX TO 1.
SEARCH MONTHLY-SALES
AT END
DISPLAY “Geen maand met de gezocht omzet.”
WHEN MONTHYLY-SALES(SALES-INDEX) = TARGET-SALES
MOVE SALES-INDEX TO FOUND
DISPLAY “Omzet van “ TARGET-SALES “ in maand “ FOUND.
END-SEARCH.
Dit programma zal de eerste maand tonen waarin de omzet 1,200,- was. Als je alle maanden wilt vinden, dan zal je de search een aantal maal moeten herhalen, waarbij je steeds de index verhoogt. Dit kan met SET SALES-INDEX UP BY 1. Verder zou het natuurlijk aardig zijn als je de gebruiker vraagt naar welke omzet gezocht moet worden, zou je kunnen zoeken naar omzet boven de gevraagde waarde, enzovoort. Ruimte voor eigen creativiteit, zolang maar duidelijk is wat een geïndexeerde table kan toevoegen bij het vinden van informatie in een table.
Wie mee wil doen met #klooienmetcomputers kan dat doen via GitHub. Maak een account op github.com en zoek naar Abmvk/kmc. Het account Abmvk volgen kan ook. Lezers zijn vrij te gebruiken wat ze willen en om zelf zaken toe te voegen of aan te passen, vragen te stellen of commentaar te leveren.
Gerelateerd
Over bits & bytes
Arnout van Kempen over rommelen in een digitale wereld.
Typecasting in COBOL
Arnout van Kempen over rommelen in een digitale wereld.
Gewone variabelen
Arnout van Kempen over rommelen in een digitale wereld.
Bestanden in soorten en maten
Arnout van Kempen over rommelen in een digitale wereld.
Alles draait om data
Arnout van Kempen over rommelen in een digitale wereld.