Livet som norsk COBOL-utvikler på 80- og 90-tallet

Per-Arne (70) om timeslang kompilering, ukeslang debugging og år 2000-problemet.

"Mann i arbeid ved datamaskiner/computere i Statistisk Sentralbyrå" forteller NTB Scanpix. Bildet er fra 1984; samme tid som Per-Arne Rindalsholt underviste COBOL-programmering på Datahøyskolen og NKI, som vi dessverre ikke finner noen bilder av . 📸: Bjørn Sigurdsøn / NTB Scanpix
"Mann i arbeid ved datamaskiner/computere i Statistisk Sentralbyrå" forteller NTB Scanpix. Bildet er fra 1984; samme tid som Per-Arne Rindalsholt underviste COBOL-programmering på Datahøyskolen og NKI, som vi dessverre ikke finner noen bilder av . 📸: Bjørn Sigurdsøn / NTB Scanpix Vis mer

Midt på 80-tallet underviste jeg flere år i COBOL-programmering på Datahøyskolen og NKI Ingeniørhøgskole. Det første semesteret hadde jeg 120 elever i klassen, senere hadde jeg «bare» 60 elever i klassen.

Jeg holdt en 4 timers forelesning en gang i uka. Presentasjonsformen var håndskrevne foiler som ble vist på overhead.

Skolen hadde et eget terminalrom, der elevene hadde tilgang til et svært begrenset antall terminaler som kunne brukes til å programmere mot en sentral datamaskin. På vanlig dagtid var det lange køer for å få tilgang til en terminal. For å få lov til å gå opp til eksamen i faget, måtte elevene ha programmert noen obligatoriske oppgaver som skulle godkjennes av en hjelpelærer.

«Åh, er du kollega av ham som underviser i sporveishistorie med COBOL-programmering attåt.»

På den tiden var det svært sjelden at noen hadde sin egen PC. De PC-ene som fantes var rådyre, og hadde kun ett programmeringsspråk: BASIC. Sherlock Holmes var langt foran sin tid da han presiserte: «Basic, my dear Watson, basic».

Med så mange elever i forelesningssalen, ble det lite dialog mellom foreleser og elever. For å unngå at alle skulle sovne, forsøkte jeg å lage litt liv i forelesningene med å fortelle noen morsomme historier.

De fleste historiene var relatert til faget, men jeg fortalte også noen historier fra en av mine hobbyer. Da en kollega av meg hadde truffet en av mine elever som hadde uttalt følgende: «Åh, er du kollega av ham som underviser i sporveishistorie med COBOL-programmering attåt», skjønte jeg at jeg kanskje hadde dratt dette litt langt.

Programmeringsspråket COBOL

COBOL var det ledende språket innen administrativ databehandling. Syntaksen lå tett opp mot det engelske språket, og var så enkel at selv firmaets direktør kunne forstå hva programmet gjorde. Bare så synd at programmereren ikke kunne si det samme.

Per-Arne Rindalsholt har blant annet jobba 38,5 år i Visma Consulting, før han pensjonerte seg denne våren. Nå forteller han om norsk programmeringshistorie på kode24. 📸: Visma
Per-Arne Rindalsholt har blant annet jobba 38,5 år i Visma Consulting, før han pensjonerte seg denne våren. Nå forteller han om norsk programmeringshistorie på kode24. 📸: Visma Vis mer

Programmene var delt i 4 divisjoner, og alle divisjonene måtte være med i ethvert program:

#1: IDENTIFICATION DIVISION
Her ga du programmet et navn.

#2: ENVIRONMENT DIVISION
Her spesifiserte du hva slags datamaskiner og modeller av disse programmet kunne kjøres på.

Du måtte også spesifisere den fysiske enhet til filene du skulle lese fra eller skrive til. Dette var gjerne monterbare disker eller taper som operatøren måtte hente i arkivet og montere, før programmet ditt kunne gå videre.

#3: DATA DIVISION
Her detaljspesifiserte du de filene du skulle lese fra eller skrive til. Filer var enten sekvensielle eller indekssekvensielle. For oss som er voksne nok til å huske telefonkatalogen på papir som ble delt ut til alle abonnentene, er det lett å forklare forskjellen på sekvensiell og indekssekvensiell lesing. Siden du visste at navnene var sortert alfabetisk, kunne du bla opp ”passelig langt uti” og deretter vurdere om du måtte gå litt lenger fram eller litt lenger tilbake. Etter å ha gjentatt dette noen ganger, fant du den aktuelle personen med langt færre oppslag enn om du hadde lest sekvensielt linje for linje fra side 1.

Bruk av databaser kom noe senere. De første databasene var hierarkiske, der du selv måtte søke deg fram til den aktuelle posten. Senere kom relasjonsdatabasene, som fremdeles er markedsledende.

«Alle variabler som skulle brukes i programmet, måtte spesifiseres ned til minst detalj.»

Alle variabler som skulle brukes i programmet, måtte spesifiseres ned til minst detalj. Her var det fort gjort å gjøre slurvefeil som fikk fatale konsekvenser. Hvis en heltallsvariabel var 3 tegn langt, og du la inn verdien 1002, regnet programmet videre med verdien 2. Og glemte du å spesifisere at en numerisk variabel skulle ha fortegn, ble alle regnskapsresultatene positive.

En variabel måtte ofte defineres 3 ganger: En variabel med skjermformattering for kommunikasjon med brukeren via skjermen, en annen variabel du kunne regne med, og en tredje variabel formattert for lagring på fil eller i database.

#4: PROCEDURE DIVISION
Endelig har du kommet til der du skal skrive behandlingsreglene dine, det de fleste anser som selve programmet. Siden mange av variablene har 3 representasjoner, ble det mye flytting av data fra den ene representasjonen til den andre med bruk av MOVE. MOVE og IF var de ordene som gikk igjen mye i ethvert COBOL program. Vi kalte oss gjerne for «MOVE-programmerere».

Jo fortere du starter å kode programmet ditt, jo lenger tid vil det ta

Ferske programmerere vil gjerne fort i gang med å kode programmet sitt. Kodingen starter gjerne før de har full oversikt over hva programmet skal gjøre. Etter noe prøving og feiling, har de endelig klart å programmere et riktig program, iallfall ut fra programmeringsspråkets krav til syntaks.

Men det er neppe det riktige programmet, det gjør ikke det det skal. Flikking på dårlige programmer ble gjerne gjort ved hjelp av diverse GO TO statement, som ikke akkurat økte lesbarheten.

Jeg fikk jobben med å programmere faktureringsrutinen til en ny bensinkortløsning for Norske Shell, kalt S-kort. Dette var en midlertidig løsning som skulle leve cirka ett år før den globale løsningen Euroshell skulle på lufta. Ja, det var frustrerende å programmere en løsning du visste skulle kastes om ett år.

Norske Shell var opptatt å få god struktur i sine IT-løsninger. De hadde kjøpt rettigheten til et verktøy for god kodestruktur som het JSP (Jackson Structured Programming) etter opphavsmannen Michael Jackson (ikke popsangeren med samme navn). Før du startet programmeringen, tegnet du bokser som viste programmets struktur:

  • Sekvens: Vanlig boks
  • Iterasjon: Boks med stjerne
  • Valg: Boks med ring

Jeg fant teknikken svært nyttig og effektiv. Med litt øvelse kunne du tegne hele programstrukturen ved hjelp av bokser, og programmeringen gikk som en lek uten et eneste GO TO statement.

Det er vanskelig å se sine egne idiotiske feil

Jeg jobbet med Postens Skrankesystem, og skulle sjekke om en transaksjon gjaldt dagens dato eller en tidligere dato. For å hente dagens dato kunne jeg bruke ACCEPT DATE. Så jeg skrev ACCEPT TIME, sjekket raskt og så at testen gikk OK.

Men neste formiddag fikk jeg plutselig behandlingsfeil i programmet, som jeg måtte lete etter årsaken til. Det så ut som om testen var i forbindelse med den datosjekken jeg hadde lagt inn dagen før.

«Men plutselig, uten at jeg hadde endret noe, fungerte plutselig programmet OK igjen.»

Men plutselig, uten at jeg hadde endret noe, fungerte plutselig programmet OK igjen. Jeg syntes det var litt rart, men man må jo ikke forstå alt her i verden.

Dagen etter oppsto feilen på nytt. Jeg fant min ACCEPT TIME, debugget og fant at verdien som gikk inn i testen var 09.08. Enda dagens dato vitterlig var 13.august! Var det feil i standardkommandoen ACCEPT TIME?

Jeg fortalte kollegaen min at var en feil med en standardkommando som vi måtte melde til maskinleverandøren. Jeg viste han programmet mitt, og kjørte en ny debug. Som nå viste verdien 09.22. Jeg ble enda mer forvirret. Men kollegaen min sa bare rolig: «Du kan prøve å se hva som skjer hvis du i stedet skriver ACCEPT DATE».

Jeg hadde testet klokkeslettet i stedet for datoen. Jeg fikk mange morsomme kommentarer en tid framover om det fine programmet mitt som virket om formiddagen, men ikke om ettermiddagen.

Noen jobber har ekspress-prioritet

Vi satt en gjeng COBOL-programmere ute hos en kunde. Et COBOL-program må rekompileres hver gang du har endret det. Kompileringen hos denne kunden tok vanligvis et par minutter.

Men en dag virket det som kompileringen hang. Jeg avbrøt den, og startet på nytt, uten at det hjalp. De andre hadde samme problem. Det virket som alt bare hang. Vi lot hver vår jobb henge, mens vi prøvde å finne på noe annet å gjøre.

Men det er ikke lett å være programmerer når du verken får kompilert eller kjørt programmet ditt, så dagen ble lite effektiv. Helt på slutten av dagen ble kompileringene endelig ferdig, og alt oppførte seg normalt igjen.

Ganske nøyaktig en måned senere oppsto den samme situasjonen. Kompileringene våre ble bare hengende. En av gutta ringte ned til driften for å høre om det var noen tekniske problemer. Nei, det var ingen problemer.

Men de holdt på å kjøre månedens lønnskjøring for alle firmaets ansatte. Dette var en stor batchjobb som hadde ekspress prioritet, det vil si at alle andre jobber ble satt på vent mens denne jobben gikk. Vår mann påpekte at vi var en gjeng eksterne konsulenter med høy timelønn som ikke fikk jobbet. Svaret var kontant: «Ingenting har høyere prioritet enn lønnskjøringen!»

Fixed file format

Input-filer var vanligvis sekvensielle filer med fixed file format. Det vil si at hvert input-felt hadde fast plass og fast lengde. Leseprogrammet kunne derfor eksempelvis hente verdien til en variabel fra posisjon 21 til 30 på input-fila. Dette er stort sett greit og oversiktlig.

Ofte er det output fra et annet program du har som input-fil til ditt program. Hvis programmet som skriver til denne fila kun har ett statement som skriver, er du sikker på at alle linjene har samme format. Men hvis programmet har flere statement som skriver til fila, kan ett av disse statementene være endret, og noen linjer på fila vil ha et annet format enn de øvrige.

«Det var mange tusen linjer i en input-fila, men hvilken var feil?»

Og det var nettopp dette jeg var utsatt for en gang. En input-kontroll sjekket at summen av alle delbeløpene inn til programmet stemte med totalbeløpet oppgitt i transaksjons-headeren. Denne kontrollen hylte og varslet feil.

Det var mange tusen linjer i en input-fila, men hvilken var feil? Etter en del forsøk på skudd i mørket, måtte jeg gå systematisk til verks.

Jeg delte input-fila i to, kjørte inn første halvdel, og denne gikk igjennom uten feil. Altså måtte dataene som var feil, ligge i den andre halvdelen. Jeg delte denne i to deler, for å identifisere i hvilken halvdel feilen lå. Og slik fortsatte jeg til jeg endelig fikk identifisert den linja som hadde feil dataformat.

Dette høres kanskje enkelt ut, men da hver testkjøring tok rundt 3 timer, og det krevdes rundt 20 kjøringer, tok feilsøkingen en hel uke. Og produksjonskjøringene ble holdt igjen hele denne uken. Det var mange utålmodige sjefer underveis som lurte på om jeg ikke fant feilen snart.

Årsaken til problemet var en nyansatt programmerer som skulle gjøre en liten, ubetydelig endring i det programmet som skrev til fila.

Endringen gjaldt en transaksjonstype som var svært lite brukt. Endringen la inn et nytt felt som var kun to tegn langt. Men dette feltet ble lagt før beløpsfeltet. Beløpsfeltet ble følgelig flyttet to posisjoner mot høyre. Og mitt program som hentet beløpsfeltet ut fra gitte posisjoner på fila, leste beløpet som kun en hundredel av hva det skulle være.

År 2000-problemet

COBOL har blitt beskyldt for å være årsaken til År 2000-problemet.

I IT-bransjens barndom var lagringsplass dyrt, og programmererne valgte derfor å bruke kun to siffer i årstall for å spare diskplass. I COBOL, som i de andre av datidens programmeringsspråk, var det programmereren selv som definerte lengden på de variable som representerte datoer og årstall. På 70-tallet var det ingen som tenkte på at kun to siffer i årstall ville bli en stor utfordring 30 år senere.

Jeg satt i sentral prosjektledelse i År 2000-prosjektet hos Rikstrygdeverket, en av forløperne til NAV, med ansvar for å sikre at alle programmer laget av og for etaten også ville fungere i det nye årtusen. Til dette arbeidet hadde jeg et budsjett på 48.000 timer.

«Det måtte bare virke, slik at folk fikk utbetalingene sine.»

Jeg kommer aldri til å glemme datoen mandag 26.11.1998, da en År 2000-tilpasset versjon av trygdeprogrammet Infotrygd ble satt i produksjon. Alle trygdekontorene i hele landet ble stengt hele fredagen, og i løpet av en svært hektisk langhelg ble databasene migrert, og nye programversjoner lagt inn og verifisert. På den tid håndterte dette programmet alle trygdeytelsene, herunder pensjon, barnetrygd og sykepenger. Det måtte bare virke, slik at folk fikk utbetalingene sine.

I ettertid ble det påstått at hele År 2000-problematikken bare var en bløff, det oppsto jo ingen store problemer. Noen bedrifter ventet bevisst med å gjøre tiltak til de så hva som gikk feil, og rettet da dette. Å kun fikse det som viste seg å feile, var en langt mindre jobb enn i forkant identifisere alt som muligens kunne gå feil, og så gjøre nødvendig tiltak.

Ut fra de testene vi gjorde i løpet av År 2000-prosjektet hos Rikstrygdeverket, kan jeg med sikkerhet si at beregning av ytelser over tusenårskillet ikke hadde fungert dersom vi hadde latt være å gjøre tilpasningene. Hadde vi ventet med tiltak til vi så hva som gikk feil, måtte trygdeutbetalingene vente minst et halvt år i påvente av nødvendige korreksjoner.