Non ho mai scritto software in Common Lisp, ma in Scheme e Clojure così come in C ++ e Python. Eppure ho dato un'occhiata al Common Lisp Object System (CLOS) in Common Lisp e Dylan. Ora, confrontandolo con OOP nella tradizione di Simula, CLOS e diciamo che il sistema di classe C ++ e Python ha il polimorfismo come tratto comune.
Sembrano differire nel modo in cui i dati e i metodi sono organizzati, nella famiglia Simula, i metodi sono parte integrante delle classi, sotto-voci se tu mentre con CLOS sono definiti al di fuori delle classi e sono procedure piuttosto generalizzate .
I sostenitori del Lisp in genere sostengono che i metodi virtuali nei linguaggi di programmazione della famiglia Simula sono piuttosto limitati poiché vengono invocati solo in base all'oggetto del primo argomento ( this
o self
). Le funzioni generiche CLOS sono selezionate per diversi argomenti, quindi qualcosa di simile (pseudo codice)
method draw(c : Device, d : Drawable) ...
può essere implementato per combinazioni arbitrarie Canvas
e Drawable
.
method draw(c : Printer, t : Triangle)....
method draw(c : Printer, t : Image)....
method draw(c : Screen, t : Image) ....
Nei linguaggi della famiglia Simula, ciò sarebbe più difficile, poiché draw
dovrebbe essere associato alla famiglia di oggetti Device
o Drawable
. La soluzione canonica sembra essere il collegamento .
Dopo aver appreso CLOS, sono rimasto piuttosto sorpreso che la maggior parte dei linguaggi di programmazione OO non offrano dispacciamenti multipli e, se ci sono ragioni specifiche, perché si possano associare i metodi così strettamente a una classe specifica. Esistono vantaggi specifici per la singola spedizione?
- ambiguità di invio multiplo: diciamo che ho
a
sottoclasseA
eb
sottoclasseB
. Il metodofoo(A,B)
implementato comefoo(a,B)
efoo(A,b)
, quale implementazione richiama una chiamata difoo(a,b)
? È questa l'unica ragione? - "Modularizzazione", i metodi nella classe sono vicini.
C'è dell'altro? I designer di lingue e i creatori hanno preso una posizione in merito?