Con la digitazione dinamica, è abbastanza semplice implementare un sistema orientato agli oggetti in termini di chiusure. Ho scritto su questo in la mia risposta a "Modellazione di oggetti come funzioni" e espanso su quello sul mio blog . Ci sono alcuni dettagli su aprire la ricorsione che sono necessari per ottenere certe funzionalità di OOP come la sottoclasse giusta, ma è fattibile. In breve, invocare la chiusura che rappresenta un oggetto associa un nome di metodo a un metodo associato a quell'oggetto, che può quindi essere invocato come una funzione ordinaria. L'utilizzo potrebbe essere simile a result = object("methodName")(otherObject)
.
Tuttavia, OOP e tipizzazione statica sono fondamentalmente in disaccordo. Esistono varie interpretazioni di OOP, come OOP-come-message-passing o OOP-as-virtual-dispatch, ma un tema centrale è che non conosciamo staticamente il tipo esatto di runtime di un'espressione come x
. Tuttavia, molti linguaggi OOP con tipizzazione statica assegnano limiti di tipo a un'espressione (ad esempio x
è un sottotipo di Iterable
). Quando si implementano gli oggetti in termini di chiusure in un linguaggio tipizzato in modo statico, si verifica rapidamente il problema: quando si specifica il metodo richiesto come argomento della funzione di invio, non è possibile conoscere staticamente la firma richiesta della funzione. Nell'esempio sopra, come faccio a sapere che il risultato di object("methodName")
dovrebbe essere una funzione che accetta esattamente un parametro?
La soluzione comune quando si implementano oggetti è rendere l'oggetto-sistema unificato (alias, non tipizzato). Cioè, tutte le firme dei metodi avrebbero lo stesso tipo indipendentemente dalla loro arità (numero di argomenti) o dai tipi di argomenti. Ciò richiede anche che tutti i nostri oggetti abbiano lo stesso tipo nella lingua host.
Alcune lingue potrebbero essere in grado di fare meglio. Per esempio. in C ++, potremmo passare il tipo di metodo richiesto come parametro del modello alla funzione di invio: auto result = object<ResultType(ArgumentType)>("methodName")(otherObject)
. Un'implementazione intelligente potrebbe quindi utilizzare diverse tabelle di ricerca per inviare int()
o int(int)
tipi di metodo, ecc. Tuttavia, non possiamo garantire staticamente che il metodo richiesto esista poiché è fornito come una stringa. Un'altra possibilità sarebbe quella di passare in un oggetto simile a "visitor-like?" Message
anziché a un nome di stringa alla funzione di invio, che potrebbe consentire più sicurezza di tipo nelle lingue host tipizzate staticamente, ma non ho esperienza sufficiente con l'implementazione di OOP in linguaggi statici per descrivere questo in modo più dettagliato.