COMAL-80
Inleiding | Programmeeromgeving | Beschrijving taal | Samenvatting ][ UniComal | OpenCOMAL
Inleiding
COMAL-80 (COMmon Algoritmic Language) is in de jaren 1973 - 1980 in Denemarken
ontwikkeld door Børge Christensen en Benedict Løfstedt, speciaal voor
gebruik in het onderwijs. Zij ontwikkelden de taal uit BASIC, voornamelijk uit onvrede met
de toenmalige Basic-versie waarin onoverzichtelijke programma-listings en
sprongconstructies met regelnummerverwijzingen eerder werden gestimuleerd dan vermeden.
De ontwerpers handhaafden de eenvoud van de BASIC-opdrachten, maar voegden er
structuurelementen van de taal Pascal aan toe, zoals procedures, functies over meer regels
gedefinieerd, voorwaardelijke uitvoering (IF...ENDIF) van blokopdrachten, de CASE-opdracht
en de herhalingsstructuren REPEAT...UNTIL en WHILE...ENDWHILE.
De leesbaarheid van de listings werd verbeterd door blokken bij elkaar behorende
programmaregels automatisch te laten inspringen en door betekenisvolle variablenamen, tot
tachtig tekens, toe te laten.
Sinds 1980 wordt over de standaard van de taal gewaakt door een internationale commissie,
waarvan onderwijsgevenden, computerfabrikanten en COMAL-deskundigen uit verschillende
landen, waaronder Nederland, lid zijn. Dankzij deze waakzaamheid zijn COMAL-80 programma's
op verschillende computersystemen volledig of nagenoeg volledig uitwisselbaar.
De COMAL-programmeeromgeving
De faciliteiten rond intoetsen en verwerken van programma's wordt bij bespreking van de
meeste talen buitenbeschouwing gelaten. Voor COMAL is de programmeeromgeving echter
gestandaardiseerd. Bij het intypen van COMAL-programma's wordt elke regel gecontroleerd op
de uiterlijke juistheid (syntax), hetgeen mogelijk is door de regel-geöriënteerdheid van
de taal. De correctheid in de samenhang van de regels blijft nog even buitenbeschouwing.
Een sytaxfout wordt onmiddellijk gemeld, bij veel systemen in het Nederlands, met
vermelding van het type van de fout en de mogelijke plaats in de regel.
Een syntactisch juiste regel wordt vastgelegd in het werkgeheugen met de volgende
wijziging: namen van variabelen, die immers erg lang mogen zijn, worden vervangen door een
verwijzing naar een naamtabel. Elke nieuwe variabele wordt bij invoering toegevoegd aan
deze tabel. De COMAL-sleuitelwoorden worden vervangen door speciale codes
("tokens").
Direct na het startem van een aldus ingevoerd programma volgt een zogenoemde
"pre-pass", waarin de programmastructuren op syntactische juistheid worden
gecontroleerd en bij goedbevinden ook de nodige verbindingen worden gelegd, zoals tussen
de aanroep en de beschrijving van een procedure of functie. Verder scheidt de pre-pass de
instructies van het commentaar (remarks). De regelnummers die met tien oplopend
automatisch door het systeem worden gegenereerd, dienen slechts voor de vastlegging van de
regelvolgorde en voor het tussenvoegen van regels. Bij listings kunnen ze worden
onderdrukt.
Omdat de computers waarop COMAL-80 geïmplementeerd is, vaak specifieke eigenschappen
hebben, zoals geluid of grafische mogelijkheden, worden uitbreiding van de standaardtaal
in de vorm van "packages" geboden. Elk package bestaat uit een aantal nieuwe
sleutelwoorden te gebruiken voor een specifieke machine-eigenschap. Een gestandaardiseerd
package is bijvoorbeeld "turtle", waarmee turtlegraphics (bekend uit de talen
LOGO en TurboPascal) aan COMAL-80 kunnen worden toegeveogd. We laten daarvan nog een
voorbeeld zien.
Korte beschrijving van de taal
COMAL-80 kent vier typen variabelen: integers (gehele getallen) met namen eidingend op #,
reals (rationale getallen), booleans (variabelen met slechts de waarden TRUE en FALSE) en
strings met namen eindigend op $. Variabelen van het type string moeten, als enige, vooraf
worden gedeclareerd (bekend gemaakt aan het systeem) om een efficiënt geheugengebruik te
bewerkstelligen.
Het programma
DIM woord$ OF 10
woord$ := "aardbei"
PRINT woord$
woord$(1 : 4) := "moer"
FOR i# := 1 TO LEN(woord$) DO
PRINT woord$(1 : i#)
ENDFOR i#
heeft als uitvoer
aardbei
m
mo
moe
moer
moerb
moerbe
moerbei
Hierboven is een string gedeclareerd van maximaal 10 tekens. Bij de waardetoekenning
wordt, evenals bijvoorbeeld in Pascal, gebruik gemaakt van het teken : = (wordt
gelijk aan).
Een string wordt daarbij opgevat als een rij afzonderlijke tekens. Dit blijkt uit het
voorbeeld, waarin via woord$(1:4) de eerste vier tekens van woord$ worden vervangen door
"moer". en uit de FOR...ENDFOR-lus, waarin telkens het af te drukken deel van
woord$ met één karakter wordt uitgebreid.
Alle variable-typen kunnen worden opgenomen in matrices (1- of meer-dimensionale
array's). De declaratie daarvan is evenseens noodzakelijk.
Bijvoorbeeld:
DIM saldo(1000)
DIM vector#(10, 10, 10)
DIM naam$(klas, leerling) OF 25
waarmee opvolgend een 1-dimensionaal array van reals, een 3-dimensionaal integer-array en een 2-dimensionaal string-array wordt vastgelegd. Uit de laatste declaratie blijkt, dat dit dynamisch kan gebeuren, dwz. met afmetingen die afhankelijk zijn van de waarde van een or meer variabelen; hier zijn dat klas en leerling.
Variabelen die aan procedures of functies worden doorgegeven - parameters genoemd - kunnen op twee manieren worden gebruikt, hetzij als waarde-parameter, hetzij als referentie-parameter. Waarde parameters hebben alleen betekenis in de procedure- of functie-beschrijving zelf; referentie-parameters geven hun waarde terug aan de oorspronkelijke -in de aanroep gebruikte- variabelen.
a := 3 bewerk(a) PRINT "a=", a // PROC bewerk(n) n := n + 1 PRINT "n=", n ENDPROC bewerk |
a := 3 bewerk(a) PRINT "a=", a // PROC bewerk(REF n) n := n + 1 PRINT "n=", n ENDPROC bewerk |
Vergelijk de uitvoer van de beide programma's:
n=4 a=3 |
n=4 a=4 |
Uit de programma's blijkt dat COMAL-keywords in hoofdletters geschreven worden. Het omzetten van kleine letters in hoofdletters gebeurt tijdens de syntax-controle. Het inspringen van de regels binnen de procedure-beschrijving geschiedt automatisch door de editor, niet alleen tijdens de invoer van het programma, maar ook bij listings op papier.
Het teken // is een zogenoemde remark. Het wordt hier gebruikt als scheider
tussen programmadelen. In het algemeen gebruikt men de remark om commentaar in listings op
te nemen.
De procedure met de naam bewerk wordt aangeroepen op de tweede programmaregel. In
de aanroep in het linker programma wordt de variabele a als waarde-parameter
gebruikt; in het rechter programma wordt a als REFerentie-parameter doorgegeven
aan de procedure.
Variabelen uit het hoofdprogramma kunnen eveneesn op twee manieren in een procedure
worden gebruikt: lokaal, dwz. dat de waarde slechts geldt binnen de procedure
zelf, en globaal, dwz. dat de waarde geldig is in het gehele programma.
Door toevoeging van het woord CLOSED aan de procedure-beschrijving worden alle
variabelen binnen die procedure lokaal (met uitzondering van die welke als
REF-parameter worden gebruikt).
Vergelijk weer
a := 3 bewerk PRINT "a=", a // PROC bewerk a := 5 a := a + 1 PRINT "a=", a ENDPROC bewerk |
a := 3 bewerk PRINT "a=", a // PROC bewerk CLOSED a := 5 a := a + 1 PRINT "a=", a ENDPROC bewerk |
met als uitvoer
a=6 a=6 |
a=6 a=3 |
Functies kunnen worden beschreven op meer dan een regel en recursie is daarbij
toegestaan. De waarde-toekenning gebeurt hierbij via een RETURN-statement.
Voorbeeld:
FUNC faculteit(n) IF n < 0 OR n <> INT(n) THEN STOP "Fout in parameter" ELIF n = 0 THEN // ELIF betekent ELSE IF RETURN 1 ELSE // recursief gebruik van de functie RETURN n * faculteit(n - 1) ENDIF ENDFUNC faculteit |
Ook het gebruik van string-functies is in COMAL-80 mogelijk.
In edit-mode kunnen de namen van procedures en functies ook als direct commando worden
gebruikt. Dit vergemakkelijkt het testen van programmadelen.
Gebruik van de taal
Door het gebruik van procedures is COMAL-80 bij uitstek geschikt voor "top-down
programmeren".
We geven hieronder een voorbeeld van een programma dat giro-overschrijvingen verricht.
voorbereiding lees_gegegevens schijf_over // PROC voorbereiding OPEN FILE 1, "saldi", RANDOM 22 // openen van een // bestand met willekeurige toegang ENDPROC voorbereiding // PROC lees_gegegevens INPUT "nummer afschrijving ": nraf INPUT "bedrag ": bedrag INPUT "nummer bijschrijving ": nrbij ENDPROC lees_gegevens // PROC schrijf_over lees(nraf, saldo) IF saldo >= bedrag THEN af bij ELSE PRINT "Tegoed ontoereikend" ENDIF ENDPROC schrijf_over // // verder in rechter kolom |
// PROC lees(record, REF getal) READ FILE 1, record: getal // lees saldotegoed ENDPROC lees // PROC af saldo := saldo - bedrag WRITE FILE 1, nraf: saldo // bijwerken afschrijving ENDPROC af // PROC bij lees(nrbij, saldo) saldo := saldo + bedrag WRITE FILE 1, nrbij: saldo // bijwerken bijschrijving ENDPROC bij |
Uit het bovenstaande programma blijkt duidelijk, dat COMAL-80 een regelgeöriënteerde
taal is; op elke regel staat slechts één statement (hoewel uitzonderingen mogelijk
zijn).
Procedures worden aangeroepen met hun naam, al of niet gevolgd door actuele parameters.
In de procedure met de naam voorbereiding wordt een bestand geopend dat
willekeurig toegankelijk is (RANDOM). Elk record in dat bestand is via een ummer
bereikbaar. De grootte van het record in bytes is van te voren vastgelegd, in dit geval
met het getal 22. Daardoor is het mogelijk verschillende waarden, zelfs van verschillend
type, in hetzelfde record op te nemen. Conversie van die gegevens is niet noodzakelijk,
omdat de componenten door het COMAL-systeem zelf gescheiden worden.
Staat er bijvoorbeeld achter het saldo in het record met nummer 10 nog de naam van de
rekeninghouder, dan kunnen saldo en naam (in die volgorde) uit het record worden gelezen
met
READ FILE 1, 10: saldo, naam$
De procedure lees illustreert nog eens het gebruik van een waarde- en een referentie-parameter.
Turtle-graphics
Zoals al even aangestipt onder Porgrammeromgeving, kan een turtle-graphics-deel, via een
zogenoemd package (of ook wel module) aan COMAL-80 worden toegevoegd en wel door het
statement
USE turtle
Mogelijke procedures zouden dan kunnen ziijn:
PROC house right(90) square(100) right(30) triangle(100) ENDPROC house |
PROC square(n) FOR keer# := 1 TO 4 DO forward(n) right(90) ENDFOR keer# ENDPROC square |
PROC triangle(n) FOR keer# := 1 TO 3 DO forward(n) right(120) ENDFR keer# ENDPROC triangle |
De procedures forward en right zijn afkomstige uit het package.
Daarin zitten ook de overige turtle-keywords zoals moveto, pencolor,
enz.
De syntax-controle op elke regel komt bij dit interactief turtle-gebruik zeer tot zijn
recht.
Samenvatting
Door zijn eenvoudige opbouw, de overzichtelijkheid en aanwezigheid van foutcontrole bij
het intoetsen van programmaregels is COMAl-80 een programmeertaal die van basisonderwijs
tot universiteit kan worden gebruikt. COMAL-80 was enkele jaren geleden nog "de
onderwijstaal" in landen als Denemarken en Ierland.
Top-down programmeren ligt met COMAL voor de hand, maar ook bottom-up is mogelijk, omdat
gebruik gemaakt kan worden van zelf-ontworpen procedurebibliotheken; via het commando
MERGE kunnen procedures aan een bestaand programma vanuit een bibliotheek worden
toegevoegd, of dynamisch tijdens de programma-uitvoering door het gebruik van EXTERNAL.
Verschillende toepassingen van automatisering zijn via COMAL-80 goed te behandelen.
Het aantal keywords in COMAL-80 is aan de hoge kant, zeker daar waar de een implementatie
van "turtle", "graphics" of geluid en bewegende beelden mogelijk is
gemaakt.
Door het gebruik van procedures, functies en doelmatige naamgeving aan variabelen is de
taal overzichtelijk en wordt er aansluiting gevonden bij andere algoritmische talen als
bijvoorbeeld Pascal.
Gegevensstructuren zijn in COMAL-80 goed weer te geven.
COMAL-80 is zeker een programmeertaal die gebruikt kan worden bij het aanvankelijk
programmeer-onderwijs.
Zie verder de pagina UniComal.
Het bovenstaande is eerder verschenen in Handboek onderwijs en computer, Samson Uitgeverij, Alphen ad Rijn, 1984.