LISP-mogelijkheden in 64 KB kerngeheugen

De IBM 704

De IBM 704 elektronische gegevensverwerkingsmachine aan het M.I.T., waarop LISP in 1960 voor het eerst werd geïmplementeerd, had 32K woorden aan 36-bit kerngeheugen [1]. In dit geval betekent dit concreet één minuscule ferrietring per bit. Er waren dus in totaal $36 \times 32768 = 1.183.608$ kleine torussen ondergebracht in een niet zo klein stalen frame. De 704 vereiste een vrij ruime kamer met versterkte vloeren en industriële airconditioning. Het totale gewicht van een typische installatie was ongeveer 10 ton.

Het LISP-systeem zelf nam 12K woorden van het kerngeheugen in beslag en één woord kon een volledige cons-cel bevatten [1], waardoor de machine iets minder dan 20K cellen aan ruimte bood aan LISP. Veel 704-installaties hadden echter slechts 8K woorden of zelfs 4K woorden aan geheugen [2] — te weinig om een LISP-systeem te draaien.

Hieronder volgt een voorbeeldprogramma van LISP 1.0 uit [1]:

DEFINE
(( (SUBST (LAMBDA (X Y Z) (COND ((ATOM Z) (COND ((EQ Y Z) X)
(T Z))) (T (CONS (SUBST X Y (CAR Z)) (SUBST X Y (CDR Z))))))) ))
()

Let op dat programma's meestal op zo weinig mogelijk regels werden getypt, omdat ze op ponskaarten moesten worden geperforeerd of via een teletype moesten worden ingevoerd die de invoer op papier kopieerde. De operator (DEFINE), de argumenten (in dubbele haakjes in het geval van DEFINE) en een omgeving moesten in drie afzonderlijke expressies aan het LISP-systeem worden geleverd.

De PDP-1

Er waren echter kleinere computers die LISP draaiden. In 1964 was er PDP-1 LISP, een implementatie voor de PDP-1 computer van DEC. Deze draaide op systemen met slechts 4096 woorden aan 18-bit opslag, waarbij het systeem zelf ongeveer 2000 woorden gebruikte [3]. Ook op de PDP-1 paste een cons-cel in een enkel woord, waardoor er ongeveer 2000 cellen beschikbaar waren voor het systeem.

Hier is een voorbeeldprogramma van PDP-1 LISP uit [3] (PDP-1 LISP maakte gebruik van kleine letters):

(rplacd (quote r1) (quote (expr (lambda (m l) (cond ((null l) m)
(t (r1 (cons (car l) m) (cdr l))))))))
(rplacd (quote reverse) (quote (expr (lambda (l) (r1 nil l)))))

Kilo LISP

Het LISP-systeem dat in het vervolg zal worden gebruikt is Kilo LISP. Dit is een portable implementatie geschreven in ANSI C (C89) die kan worden gecompileerd tot een tiny model PC-DOS executable dat draait in 64 KB geheugen.

Het LISP-systeem zelf neemt ongeveer 13 KB in beslag, waardoor er genoeg ruimte overblijft voor 8192 cons-cellen. Elke cel reserveert 5 bytes (16 bits car, 16 bits cdr en 3 bits tag, waarbij die laatste wordt afgerond naar 8 bits).

Hier is een voorbeeldprogramma:

(setq assoc
(lambda (x a)
(cond ((null a) nil)
((eq x (caar a)) (car a))
(else (assoc x (cdr a))))))

Vergelijking en Context

Het Kilo LISP-systeem biedt minder dan de helft van de cons-cellen van een grote IBM 704-installatie, maar ongeveer vier keer zoveel ruimte als een minimale PDP-1.

Natuurlijk waren oude computers traag: de IBM 704 had een kloksnelheid van 40 kHz (0,04 MIPS) en de PDP-1 werkte op 150 kHz (0,15 MIPS). Echter, de LISP-systemen op die machines waren zorgvuldig handmatig geschreven assembly-programma's en hun hardware voerde doorgaans één instructie per klokcyclus uit.

Tegenwoordig kun je waarschijnlijk een IBM 704 en een PDP-1 emuleren op een goedkope smartphone, waarbij beide draaien op een veelvoud van de snelheid van de originele hardware, terwijl je ondertussen je favoriete jump-and-run spel speelt. Hoewel een 704 of een PDP-1 waarschijnlijk alle volgende voorbeeldprogramma's zou kunnen draaien, zouden ze daar zeker de tijd voor nemen. De rest van dit essay zal zich concentreren op het geheugenaspect en de aanlooptijden negeren.

Hier is een eerste indruk van hoe antiek LISP aanvoelt.