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.

begin pagina
[comal.htm] laatste wijziging op: 16-03-2006