2022-04-26

Grace Hopper och den första kompilatorn

Flottiljamiral Grace Hopper (1906–1992) vid kontrollbordet till en UNIVAC I, ca 1960. Är hon känd? Det borde hon vara; Grace Hopper är ett av de största namnen i tidig datahistoria.

Det innebär inte att hon gjort allt hon tillskrivits.

Karriären bedrevs i USA:s flotta där hon under andra världskriget arbetade med datorer (beräkningsautomater). Hon fann dem krångliga att programmera, och konstruerade därför ett program som kunde översätta text till datorspråk. Uppfinningen var världens första kompilator, Flow-matic, och den färdigställdes 1952.

- Internetmuseum: Grace Hopper

In 1951, she created the first “compiler,” a program that would translate a new, more human-friendly set of instructions into machine code automatically.

- Steven Poole, Grace Hopper: The Most Important Female Computer Pioneer You’ve Never Heard Of, New York Magazine 4 november 2016

Nu är tidig datahistoria inte så enkel att begripa sig på, ens om man kan en del om senare datorer, programmeringsspråk och så. Därför är det inte så konstigt att det blir fel ibland. Särskilt när man vill upphöja någon som det verkligen finns skäl att upphöja. Och det blir inte enklare när vederbörande själv blandar ihop korten, med eller (som jag tror och hoppas) utan flit.

Så Grace Hopper skulle ha skapat den första kompilatorn. Vad är en kompilator? "Ett program som kunde översätta text till datorspråk"? Den beskrivningen är en liten bit på vägen, men inte mer.

Att snabbt och begripligt förklara de relevanta skillnaden mellan hög- och lågnivåprogrammering är sannerligen en utmaning, men här är ett försök … Givetvis med en skopa förenklingar; här hoppar jag gärna över sanningar som komplicerar bilden för det här skrivs inte för proffsen.

En dator förstår egentligen ett och endast ett programmeringsspråk, nämligen så kallad maskinkod. En PC talar ett sådant språk, Macar, iPhone och iPad ett annat. Till exempel. Maskinkod kan se lite eller ganska olika ut från maskin till maskin, men principerna skiljer sig inte jättemycket. En sak de har gemensamt är att programmering i maskinkod, om det inte gäller pyttesmå program, snabbt och lätt blir ett omständligt pilljobb – som att bygga ett hus i full skala med legobitar. Besvärligt att göra, än värre att leta fel i programmen, och kommer man så småningom på (och det gör man alltid) att det här ville jag ha på ett annat sätt – ja, då är maskinkod synnerligen otacksamt att arbeta med. 

Så maskinkod undviker man att arbeta med om man inte måste. Istället använder man något av de myriader andra programmeringsspråk, så kallade högnivåspråk, som folk utvecklat genom åren – Fortran, Cobol, Pascal, C, Java, Perl, Python, Ruby och allt vad de heter. Då kan man skriva saker som, skrivet med kod som liknar de flesta nämnda språken, if (a != b) print(a/3), vilket utläses "om variablerna a och b är olika så skriv ut (på skärmen) en tredjedel av värdet av a". Med lite vana kan även betydligt krångligare satser än så läsas utan större besvär. Att få samma sak gjort i maskinkod … Ja, visst går det, absolut, men redan det triviala exemplet kan bjuda på en del krångel. Läsbart blir det inte. Att skriva en miniräknare, en habil browser eller ett system för att identifiera och genskjuta inkommande robotar kan vara en större eller mindre utmaning i högnivåspråk. Att göra detsamma i maskinkod får jag ont i magen bara av att tänka på.

De första datorerna programmerades givetvis i maskinkod. På den tiden kunde skillnaderna mellan olika datorers maskinkod vara betydligt större än de är idag. Att lära och lära om maskinkod för marknadens alla modeller utgjorde en stor del av programmeraryrket. När man så småningom kom på att man kunde ta fram högnivåspråk och skriva programmen i sådana, så var det början på ett av de stora, grundläggande stegen i datorernas utveckling. Men riktigt fint blev det först när man skrev program som översatte programmen skrivna i högnivåspråk till program i maskinkod. Då kunde man låtsas som om datorn begrep print(a/3) osv. Man behövde inte ens bekymra sig för datorns märke och modell – man skrev sitt program i det högnivåspråk man kände för, och kunde strunta i hur dess maskinkod såg ut.

Program som översätter högnivåspråk till maskinkod kallas kompilatorer. Även om du aldrig hört talas om företeelsen så är de en hörnsten i datavärlden, och därmed i vår digitaliserade vardag. Minsta lilla app du använder har skrivits i ett högnivåspråk, och sedan kompilerats till maskinkod så den kan användas på din dator, padda eller mobil.

Därmed är den första kompilatorn en milsten i datahistorien, och det är inte lite ära som tillfaller den som skapade den. Snarare är det märkligt att det inte uppmärksammats mer – eller, det visar att vi i allmänhet inte är så datoriserade som vi kanske tror (vi använder datorer närmast konstant, men vet inte, och vill inte veta, hur de fungerar).

Vem var det då som skapade den första kompilatorn? Påståendet ovan har cirkulerat länge: Grace Hopper. Där det naturligtvis är extra tacksamt att för en gångs skull kunna ge äran för ett datalogiskt genombrott till en kvinna (mer om den aspekten av datahistorien i bloggposten Hur datorer blev en killgrej).

Men är det sant? Nu blir det mer komplicerat. Också för att så olika uppgifter förekommer. En del av förvirringen kan ha tekniska orsaker, men långt ifrån allt.

Här är ett citat:

The first practical compiler was written by Corrado Böhm, in 1951, for his PhD thesis. The first implemented compiler was written by Grace Hopper, who also coined the term "compiler", referring to her A-0 system which functioned as a loader or linker, not the modern notion of a compiler. The first Autocode and compiler in the modern sense were developed by Alick Glennie in 1952 at the University of Manchester for the Mark 1 computer.

- Wikipedia: History of compiler construction#First compilers

Jag vet inte riktigt vilken skillnad man lägger mellan practical och implemented, men Böhms insats verkar ha varit av det akademiska slaget, Hoppers mer praktisk: En kompilator som inte är implementerad, skriven och klar att använda är en teoretisk konstruktion som man kanske kan ha användning av i avhandlingar men inte i verkligheten.

Hopper skrev sitt "A-0" från oktober 1951 till maj 1952 (Kathleen Williams Grace Hopper: Admiral of the Cyber Sea (2012)) på en UNIVAC I – datorn på bilden som inleder denna bloggpost. (Notera även att Internetmuseum ovan måtte ha blandat ihop det enklare och tidigare systemet A-0 med språket FLOW-MATIC som Hopper tog tag i från 1955.)

Men vad var A-0? Varför kallas det "system" ovan istället för "språk"? För att det snarare var ett "system" än ett "språk", så som vi tänker på det idag.

A program was specified as a sequence of subroutines and its arguments. The subroutines were identified by a numeric code and the arguments to the subroutines were written directly after each subroutine code. The A-0 system converted the specification into machine code that could be fed into the computer a second time to execute the said program.

- Wikipedia: A-0

"Konvertera till maskinkod" låter som en kompilator. Det gör även inledningen nedan, "översätta till maskinkod". Men det motsägs av de mer detaljerade beskrivningarna. Den konvertering/översättning det var frågan om var mycket enklare än det som senare kompilatorer gjorde och gör.

The A-0 System was a set of instructions that could translate symbolic mathematical code into machine language. In producing A-0, she took all the subroutines she had been collecting over the years and put them on tape. Each routine was given a call number, so that it the machine could find it on the tape. "All I had to do was to write down a set of call numbers, let the computer find them on the tape, bring them over and do the additions. This was the first compiler," as described by Grace.

- Computing History: 1952 – Grace Hopper completes the A-0 Compiler

Det där är inte en kompilator, åtminstone inte så som uttrycket används idag. Med modernt dataspråk skulle den kallas en länkare: Den tar ett antal kompilerade kodstycken och sätter ihop dem till ett fungerande program. Sådana kodstyckena kan till exempel utgöras av färdiga programbibliotek, som programmerare kan använda utan att ideligen behöva uppfinna hjulet. Närmare bestämt är det exakt sådana bibliotek som Hoppers A-0 använde sig av: Färdiga rutiner för att, tja, räkna ut medelvärden eller kvadratrötter eller vad det nu kan ha varit, som man sedan kunde använda genom att be A-0 att "använda rutin 18" eller så. Sannerligen ingen dålig besparing i tid och arbete, och avgjort ett viktigt steg i programmeringens historia. Men en kompilator? Som översätter högnivåspråk till maskinkod? Nej.

En utmanare till första kompilator-priset, som jag aldrig hört talas om förrän jag började läsa in mig på ämnet, är nämnda Autocode av Alick Glennie; "considered by some to be the first compiled programming language" som det står i Wikipedia: Autocode, där man kan fundera på vilka som är "some" och varför folk här inte är överens. 

Här är en ekvation:

 

Lite mer komplicerat än "om a och b är olika", men inte i närheten av vad man kan stöta på ute i verkligheten. Det där vill man inte skriva i maskinkod om man kan slippa. I ett tänkt högnivåspråk skulle jag skriva högra ledet som sqr(abs(t))+5*t^3 ungefär. Hur gjorde Glennie? Han skapade ett system där han kunde skriva så här:

Det där ser inte så värst "högnivåaktigt" ut. Men det är utan tvivel vida enklare än att skriva maskinkod. Icke desto mindre verkar hans insats inte ha gjort något mätbart intryck.

Men om Hopper inte skapade en kompilator, och vad än Böhm och Glennie gjorde har glömts bort, när och vad var då den faktiska första kompilatorn som lämnade ett teknikhistoriskt minne?

I Wikipedia-artikeln närmast ovan följs de tre namnen av följande:

The FORTRAN team led by John W. Backus at IBM introduced the first commercially available compiler, in 1957

- Wikipedia: History of compiler construction#First compilers

FORTRAN är ett avgjort tråkigare svar än Grace Hopper. Fortran (som länge skrevs med versaler, då sådant länge var "data-mässigt") är välkänt i branschen som det första högnivåspråket, ett levande fossil (skulle en del säga) som fortfarande hänger kvar lite här och var. För att kunna köra det krävdes en kompilator, i dagens betydelse. Ett sådant program är långt mer komplicerat än en aldrig så användbar länkare. Och långt mer kraftfullt; att sy ihop subrutiner kan vara nog så användbart, men det är inte som att programmera ett högnivåspråk. Och långt mer krävande; de åtta månader som Hopper (ensam, antar jag här) tillbringade med A-0 kan jämföras med de 18 manår som den första Fortran-kompilatorn tog att utveckla.


Om Grace Hopper påstås även saker om COBOL som verkar vara värda att studera. Liksom att hon skulle ha myntat ordet bug om fel i dataprogram, vilket är lätt att visa är fel: Se bloggposterna First actual bug och Very first actual bug.


Inga kommentarer: