BESLUIT

In deze cursus zijn bijna alle primitieve dataypes, procedures en controlestructuren van Scheme aan bod gekomen. Enkele in dit document niet gebruikte numerieke primitieven werden overgeslagen. Zie de definitie van SCHEME We besluiten met enkele bedenkingen over de historie en verdiensten van LISP.

Geschiedenis van LISP

LISP (LISt Processing) is samen met Fortran één van de oudste hogere programmeertalen. De taal werd eind jaren vijftig door John McCarthy (een van de founding fathers van de AI) ontworpen als een taal voor het beschrijven en oplossen van symbolische wiskundige problemen zoals symbolische differentiatie en integratie van algebraïsche expressies en recursieve vergelijkingen (in plaats van de numerieke wiskundige problemen waar Fortran uitstekend geschikt voor was).

Bijvoorbeeld, de recursieve wiskundige definitie voor de functie faculteit,

0! = 1
n! = n(n-1)!

staat heel dicht bij de manier waarop de functie in LISP geïmplementeerd wordt:

> (define (! n)   
    (if (< n 2)        
        1                 
        (* n (! (- n 1)))))

> (! 4)                 
24

Tot het midden van de jaren tachtig ontstond een proliferatie van LISP varianten en dialecten. In Figuur 1 staat een gedeeltelijke stamboom van LISP. Common Lisp (Steele, 1990) is een poging om een standaard te ontwikkelen die de beste en meest gebruikte elementen van veel van de verschillende bestaande dialecten verenigde. Deze standaard zorgde tegelijk voor het in onbruik raken van illustere voorgangers als Franz Lisp, Interlisp en ZetaLisp. Sommige dialecten slagen er in voort te leven naast Common Lisp omwille van interessante eigenschappen. SCHEME, bijvoorbeeld, is een kleinere, meer `pure' vorm van LISP. Common LISP biedt een grote keuze aan primitieve en complexe datastructuren (arrays, hash-tables, strings, bitstrings, structures, objects, ...) en controlestructuren (verschillende iteratie constructies, conditionele constructies, input- en output-primitieven, ...). Dat is ideaal voor de ontwikkeling van complexe software systemen. Voor onderwijsdoeleinden, daarentegen, is de eenvoudige definitie van SCHEME beter geschikt.

Stamboom Lisp dialecten

Een functionele declaratieve taal

LISP is een declaratieve taal (zoals PROLOG), in tegenstelling tot de meeste hogere programmeertalen (Pascal, Basic, Fortran, Algol, C) die imperatief zijn (een opeenvolging van imperatieve commando's, subroutine aanroepingen en toekenningen van waarden aan variabelen). PROLOG is een relationele declaratieve taal (gebaseerd op de declaratieve beschrijving van relaties tussen entiteiten), en LISP is een applicatieve of functionele declaratieve taal, gebaseerd op functietoepassing. Het onderscheid is natuurlijk niet zo duidelijk als we zouden willen. Het is best mogelijk om functioneel te programmeren in Pascal, of imperatief in LISP. Het gaat hier om de programmeerstijl die het meest natuurlijk is voor de verschillende talen.

LISP en AI

LISP werd snel de meest gebruikte programmeertaal van onderzoekers en ontwikkelaars op het gebied van Kunstmatige Intelligentie (Artificial Intelligence, AI). Dat is ze trouwens nog steeds in de VS en grote delen van Europa. Sinds de jaren tachtig werd PROLOG een sterk alternatief, vooral in Japan en Europa. Niet alleen zijn er een aantal praktische en programmeertechnische voordelen bij het gebruik van LISP voor AI die we elders beschrijven, LISP belichaamt ook de belangrijkste theoretische hoeksteen van de hedendaagse AI en Cognitiewetenschap: intelligent gedrag is het resultaat van symboolmanipulatie. Deze stelling is bekend onder de namen Physical Symbol System Hypothesis (PSSH) of Representational Theory of Mind.

Vereenvoudigd komt de PSSH (Newell, 1980) hierop neer:

  1. Primitieve mentale concepten worden gerepresenteerd in een intelligent systeem door fysieke symbolen.
  2. Complexe mentale concepten worden gerepresenteerd als structuren van fysieke symbolen.
  3. Intelligentie (een verzameling intelligente functies) is het resultaat van de manipulatie van structuren van fysieke symbolen. Die manipulatie gebeurt door programma's.
  4. Programma's kunnen gerepresenteerd worden als fysieke symbool structuren. Op die manier kan een intelligent systeem leren (door de manipulatie van symboolstructuren die programma's representeren).

De primitieve datastructuren van LISP (symbolen en lijsten) laten een gemakkelijke implementatie van symboolstructuren en van de compositionele aard van complexe concepten toe, terwijl (samengestelde) functietoepassing een natuurlijke manier is om symboolstructuurmanipulatie uit te drukken. Bovendien worden programma's en data op dezelfde manier gerepresenteerd in LISP (als lijsten: vergelijk de data '(1 2 3) met het `programma' (+ 2 3)) wat de weg opent naar modificatie of constructie van programma's door programma's.

De LISP programmeeromgeving

Naast het parallellisme tussen het ontwerp van LISP en de theoretische basis van AI en cognitiewetenschap, zijn er een aantal eigenschappen van LISP die het tot een bijzondere en belangrijke taal voor AI onderzoek maken, zelfs voor onderzoekers die andere hogere programmeertalen kennen.

Lisp is niet alleen de moedertaal van de AI, het is ook een goede keuze voor om het even welk type van complexe, slecht-gedefinieerde problemen, en voor elk programmeerproject waar produktiviteit een rol speelt. De meeste moderne LISP compilers zijn ook efficiënt genoeg, zelfs voor specifieke number crunching toepassingen.

Toch mogen we niet blind zijn voor het feit dat ondanks het bestaan van standaarden voor SCHEME en Common Lisp, en de al eerder genoemde voordelen, LISP nooit doorgebroken is als implementatiemedium voor de productie van industriële software systemen. Lisp omgevingen worden bijna uitsluitend gebruikt bij prototyping van complexe software systemen. Om aantrekkelijk te zijn voor de software engineering markt moet nog verder gewerkt worden aan de programmeeromgeving (vooral m.b.t. de gewoontes en wensen van software engineers), aan verdere standaardisering, en aan de opleiding van Lisp programmeurs. De veelgeprezen flexibiliteit van LISP maakt het helaas ook mogelijk om slechte en inefficiënte code te schrijven. Voor een recent overzicht van de standaardiseringspogingen van Lisp en een originele visie op de mogelijkheden van en mythes en misverstanden rond Lisp, zie Richard P. Gabriel (1991).

Prolog versus LISP

Prolog en LISP zijn beide declaratief, en worden beide gebruikt in AI toepassingen. Het debat over de respectievelijke voor- en nadelen van PROLOG en LISP bij de ontwikkeling van AI-systemen heeft vaak iets van een religieuze oorlog. Het is aan te raden een agnostisch standpunt in te nemen.

Prolog heeft een impliciet redeneermechanisme (unificatie en depth first backward chaining van regels), en is daarom ideaal voor een klasse van problemen die veel voorkomt in de AI (o.m. in parsing, planning en expertsystemen).

LISP is neutraal m.b.t. het redeneermechanisme, en is daarom meer algemeen toepasbaar. Voor de PROLOG klasse van problemen zou in LISP een expliciete unificatie en backward chaining controlestructuur geschreven worden. LISP kan dus omschreven worden als een wat minder `hoge' programmeertaal dan PROLOG, maar tegelijk wat meer flexibel dan Prolog. (Prolog staat op het niveau van een extensie van LISP).


Walter Daelemans <Walter.Daelemans@kub.nl>
Last modified: Tue Mar 18 15:55:49 1997