Common Lisp Object System

Standard metodkombination i ANSI common lisp

Common Lisp Object System (CLOS) är anläggningen för objektorienterad programmering som är en del av ANSI Common Lisp . CLOS är ett kraftfullt dynamiskt objektsystem som skiljer sig radikalt från OOP-faciliteterna som finns i mer statiska språk som C++ eller Java . CLOS inspirerades av tidigare Lisp-objektsystem som MIT Flavors och CommonLoops , även om det är mer generellt än båda. Ursprungligen föreslogs som ett tillägg, CLOS antogs som en del av ANSI-standarden för Common Lisp och har anpassats till andra Lisp-dialekter som EuLisp eller Emacs Lisp .

Funktioner

De grundläggande byggstenarna i CLOS är metoder , klasser , instanser av dessa klasser och generiska funktioner . CLOS tillhandahåller makron för att definiera dessa: defclass , defmethod och defgeneric . Instanser skapas med metoden make-instance .

Klasser kan ha flera superklasser , en lista med slots (medlemsvariabler i C++/Java-språk) och en speciell metaklass . Slots kan tilldelas efter klass (alla instanser av en klass delar platsen) eller efter instans. Varje plats har ett namn och värdet på en plats kan nås med det namnet med funktionen slot-värde . Dessutom kan speciella generiska funktioner definieras för att skriva eller läsa värden för slots. Varje plats i en CLOS-klass måste ha ett unikt namn.

CLOS är ett system för flera sändningar . Detta innebär att metoder kan specialiseras på något eller alla av deras erforderliga argument. De flesta OO-språk är single-dispatch, vilket innebär att metoderna bara är specialiserade på det första argumentet. En annan ovanlig egenskap är att metoder inte "tillhör" klasser; klasser tillhandahåller inte ett namnutrymme för generiska funktioner eller metoder. Metoder definieras separat från klasser och de har ingen speciell åtkomst (t.ex. "det här", "själv" eller "skyddat") till klassplatser.

Metoder i CLOS är grupperade i generiska funktioner . En generisk funktion är ett objekt som är anropbart som en funktion och som associerar en samling metoder med ett delat namn och argumentstruktur, var och en specialiserad för olika argument. Eftersom Common Lisp tillhandahåller icke-CLOS-klasser för strukturer och inbyggda datatyper (siffror, strängar, tecken, symboler, ...), fungerar CLOS-dispatch även med dessa icke-CLOS-klasser. CLOS stöder även sändning över enskilda objekt (eql-specialister). CLOS stöder inte som standard sändning över alla Common Lisp-datatyper (till exempel fungerar inte sändning för helt specialiserade arraytyper eller för typer som introduceras av deftype ). De flesta Common Lisp-implementeringar tillhandahåller dock ett metaobject-protokoll som tillåter generiska funktioner att tillhandahålla applikationsspecifik specialisering och sändningsregler.

Utskick i CLOS skiljer sig också från de flesta OO-språk:

  1. Med en lista med argument bestäms en lista över tillämpliga metoder.
  2. Denna lista är sorterad efter specificiteten hos deras parameterspecialister.
  3. Utvalda metoder från denna lista kombineras sedan till en effektiv metod med den metodkombination som används av den generiska funktionen.
  4. Den effektiva metoden anropas sedan med de ursprungliga argumenten.

Denna sändningsmekanism fungerar under körning. Att lägga till eller ta bort metoder kan således leda till ändrade effektiva metoder (även när den generiska funktionen anropas med samma argument) vid körning. Att ändra metodkombinationen kan också leda till olika effektiva metoder.

Till exempel,


   


    
  

    


     
  

       ; Deklarera prototypen för den gemensamma argumentstrukturen.   (  defgenerisk  f  (  xy  )  )  ; Definiera en implementering för (f heltal t), där t matchar alla typer.   (  defmetod  f  ((  x  heltal  )  y  )  1  )  (  f  1  2.0  )  =>  1  ; Definiera en implementering för (f heltal reellt).   (  defmethod  f  ((  x  heltal  )  (  y  real  ))  2  )  (  f  1  2.0  )  =>  2  ; Utskick ändrades vid körning. 

Liksom OO-systemen i de flesta dynamiska språk , tvingar CLOS inte inkapsling . Alla slot kan nås med hjälp av slot-value- funktionen eller via (valfritt autogenererade) accessormetoder . För att komma åt den via slot-value måste du känna till namnet på sloten. CL-programmerare använder språkets paketfunktion för att deklarera vilka funktioner eller datastrukturer som är avsedda för export.

Förutom normala ("primära") metoder finns det också :före , :efter och :around "hjälpmetoder". De två förstnämnda anropas före eller efter den primära metoden, i en viss ordning baserat på klasshierarkin. En :around- metod kan styra om den primära metoden överhuvudtaget exekveras. Dessutom kan programmeraren specificera om alla möjliga primära metoder längs klasshierarkin ska anropas eller bara den som ger den närmaste matchningen.

Standardmetoden -kombinationen tillhandahåller de primära, före, efter och runt metoderna som förklaras ovan. Det finns andra metod-kombinationer med andra metodtyper. Nya (både enkla och komplexa) Metodkombinationer och metodtyper kan definieras.

CLOS tillåter flera arv . När standardordningen i vilken metoder exekveras i multipelt arv inte är korrekt, kan programmeraren lösa diamantarvsproblemen genom att specificera ordningen för metodkombinationer.

CLOS är dynamiskt, vilket innebär att inte bara innehållet utan även strukturen på dess objekt kan ändras under körning. CLOS stöder ändring av klassdefinitioner i farten (även när instanser av den aktuella klassen redan finns) samt ändring av klassmedlemskapet för en given instans genom ändringsklassoperatorn . CLOS låter dig också lägga till, omdefiniera och ta bort metoder under körning. Cirkel -ellipsproblemet löses lätt i CLOS, och de flesta OOP- designmönster försvinner antingen eller är kvalitativt enklare.

CLOS är inte ett prototypspråk : klasser måste definieras innan objekt kan instansieras som medlemmar av den klassen.

Metaobject Protocol

Utanför ANSI Common Lisp-standarden finns det en brett implementerad tillägg till CLOS som kallas Metaobject Protocol (MOP). MOP definierar ett standardgränssnitt till grunden för CLOS-implementeringen, behandlar klasser, slot-beskrivningar, generiska funktioner och metoder själva som instanser av metaklasser och tillåter definition av nya metaklasser och modifiering av allt CLOS-beteende. Flexibiliteten hos CLOS MOP föreställer aspektorienterad programmering , som senare utvecklades av några av samma ingenjörer, som Gregor Kiczales . MOP definierar beteendet för hela objektsystemet genom en uppsättning protokoll. Dessa definieras i termer av CLOS. Således är det möjligt att skapa nya objektsystem genom att utöka eller ändra den tillhandahållna CLOS-funktionaliteten. Boken The Art of the Metaobject Protocol beskriver användningen och implementeringen av CLOS MOP.

De olika Common Lisp-implementeringarna har något olika stöd för Meta-Object Protocol. Closer - projektet syftar till att tillhandahålla de funktioner som saknas.

Influenser från äldre Lisp-baserade objektsystem

Flavors (och dess efterföljare New Flavours) var objektsystemet på MIT Lisp Machine . Stora delar av Lisp Machines operativsystem och många applikationer för det använder Flavors eller New Flavours. Smaker introducerade flera arv och blandningar , bland andra funktioner. Smaker är för det mesta föråldrade, även om implementeringar för Common Lisp finns. Flavors använde paradigmet för budskapspassering. Nya smaker introducerade generiska funktioner.

CommonLoops var efterföljaren till LOOPS (från Xerox Interlisp -D). CommonLoops implementerades för Common Lisp. En bärbar implementering kallad Portable CommonLoops (PCL) var den första implementeringen av CLOS. PCL är brett portad och utgör fortfarande basen för CLOS-implementeringen av flera Common Lisp- implementationer. PCL implementeras mestadels i bärbar Common Lisp med endast ett fåtal systemberoende delar.

CLOS på andra programmeringsspråk

På grund av kraften och uttrycksfullheten hos CLOS, såväl som den historiska tillgängligheten av Tiny CLOS (en förenklad bärbar CLOS-implementation skriven av Gregor Kiczales för användning med Scheme), har CLOS-liknande MOP-baserade objektsystem blivit de facto normen i de flesta Lisp dialektimplementeringar, såväl som att hitta in i några andra språks OOP -faciliteter:

Vidare läsning

  •    Bobrow, Daniel G. ; Kahn, Kenneth; Kiczales, Gregor ; Master, Larry ; Stefik, Mark; Zdybel, Frank (juni 1986). "CommonLoops: Merging Lisp och objektorienterad programmering" (PDF) . Konferenshandlingar om objektorienterade programmeringssystem, språk och applikationer . OOPSLA '86. s. 17–29. doi : 10.1145/28697.28700 . ISBN 978-0-89791-204-4 . S2CID 62631315 . Hämtad 2022-03-17 .
  •   Veitch, Jim (1998). "En historia och beskrivning av CLOS". I Salus, Peter H. (red.). Handbook of Programming Languages, Volym IV: Funktionella och logiska programmeringsspråk (1:a upplagan). Macmillan Technical Publishing. s. 107–158. ISBN 1-57870-011-6 .
  1. ^ "CLOS är en standard. Flera leverantörer tillhandahåller CLOS. CLOS (eller delar av det) används för att lägga till objektorientering till andra Lisp-dialekter som EuLisp eller Emacs Lisp." sid. 110 av Veitch 1998
  2. ^ I bilderna Design Patterns in Dynamic Languages ​​presenterar Peter Norvig sina upptäckter att 16 av 23 designmönster hämtade från olika läroböcker är antingen "osynliga eller enklare" i Dylan eller Common Lisp än i C++.
  3. ^ Närmare projekt: Närmare MOP
  4. ^   Deniau, Laurent (12 mars 2010). C-objektsystemet: Använder C som ett objektorienterat språk på hög nivå ( PDF) . arXiv : 1003.2547 . CiteSeerX 10.1.1.763.7946 . Hämtad 2022-03-17 .
  5. ^ Dynace Object Oriented Extension to C
  6. ^    Newton, Jim; Rhodes, Christophe (28 november 2008). "Anpassade specialister på objektorienterad Lisp" . Journal of Universal Computer Science . 14 (20): 3370–3388. CiteSeerX 10.1.1.523.2413 . doi : 10.3217/jucs-014-20-3370 . S2CID 12032836 . Hämtad 2022-03-17 .
  7. ^ Tiny CLOS, utvecklad av Gregor Kiczales

Litteratur