Perché molti linguaggi di programmazione dinamica duck-type dovrebbero utilizzare un approccio di classe anziché OOP basato su prototipo?


23

Dato che molti linguaggi di programmazione dinamici hanno la caratteristica della tipizzazione duck , e possono anche aprire e modificare metodi di classe o istanza in qualsiasi momento (come Ruby e Python ), quindi ...

Domanda 1) Qual è la necessità di una lezione in un linguaggio dinamico? Perché il linguaggio è progettato in questo modo per usare una classe come una sorta di "modello" invece di farlo come prototipo e semplicemente usare un oggetto?

Anche JavaScript è basato sul prototipo, ma CoffeeScript (la versione avanzata di JavaScript) sceglie il modo basato sulla classe. E lo stesso vale per Lua (basato su prototipo) e MoonScript (basato su classe). Inoltre, c'è classe in ES 6. Quindi ...

Domanda 2) Sta suggerendo che se si tenta di migliorare un linguaggio basato su prototipo, tra le altre cose, è necessario modificarlo in classe? In caso contrario, perché è progettato in questo modo?


9
Molti programmatori non vogliono preoccuparsi di imparare qualcosa di nuovo. (È troppo estraneo e "difficile"). Da qui tutte quelle librerie e linguaggi basati su classi che li compilano.
Thomas Eding,

1
Sono d'accordo con Thomas, ma la cosa divertente è che dopo aver appreso l'approccio dinamico, in realtà è più facile (non più difficile). Il concetto di oggetti è ancora lì, è solo che gli oggetti possono essere cambiati senza ricompilare prima qualche stupido "progetto". Se voglio mettere una 5a gamba su una sedia, non voglio prima cambiare un progetto, voglio solo aggiungere la gamba. I linguaggi dinamici modellano più da vicino la realtà secondo me.
Lonnie Best

1
OOP è stato inventato in un contesto tipicamente statico, in cui i tipi devono essere dichiarati. Lì, le classi sono un sensibile passo avanti rispetto ai record e ai moduli. OOP basato su prototipo è sempre stato un argomento di ricerca interessante per il linguaggio autonomo e in qualche modo è diventato JavaScript come il modo più semplice per spuntare la parola d'ordine "OOP" per un linguaggio essenzialmente funzionale. La cosa bella è che puoi implementare le classi in cima ai prototipi. Mentre mi piacciono i metaobject, separare le classi dalle loro istanze rende più semplice la scrittura di codice ben fatto, semplice, liberamente accoppiato.
am

3
Prima cosa: JavaScript stesso supporta la classparola chiave a partire dal prossimo standard ECMAScript (ECMAScript 6). Il supporto per le lezioni in JavaScript è pianificato da molto tempo. Ora per quello che è: le classi sono solo zucchero sintattico, un motivo più facile da ragionare sul modello per oggetti dello stesso tipo. È così in JS ed è così in Python e in altri linguaggi dinamici.
Benjamin Gruenbaum,

1
@BenjaminGruenbaum "... le lezioni sono solo zucchero sintattico ..." wow, questa è una specie di idea piuttosto nuova per me, davvero, per linguaggi come ruby ​​e python, sembra che non importa se usare un oggetto o classe come modello: entrambi possono comunque essere modificati al volo. E non importa nemmeno come gestiscono l'eredità. Quindi, forse non c'è bisogno di distinguere tra l'approccio basato sulla classe e l'approccio basato sui prototipi per un linguaggio dinamico :)
iceX

Risposte:


12

Domanda 1) Qual è la necessità di una lezione in un linguaggio dinamico? Perché il linguaggio è progettato in questo modo per utilizzare una classe come una sorta di "modello" invece di farlo come prototipo e semplicemente usare un oggetto?

Il primissimo linguaggio OO (anche se non si chiamava "OO"), Simula, non aveva eredità. L'ereditarietà è stata aggiunta in Simula-67 ed era basata su classi.

Più o meno nello stesso periodo, Alan Kay iniziò a lavorare sulla sua idea di un nuovo paradigma di programmazione, che in seguito chiamò "Orientamento agli oggetti". Gli piaceva molto l'eredità e voleva averlo nella sua lingua, ma non gli piacevano affatto le lezioni. Tuttavia, non riuscì a trovare un modo per avere eredità senza classi, e così decise che non gli piaceva le classi più di quanto gli piacesse l'eredità e progettò la prima versione di Smalltalk, Smalltalk-72 senza classi e quindi senza eredità.

Un paio di mesi dopo, Dan Ingalls inventò un progetto di classi, in cui le classi stesse erano oggetti, vale a dire casi di metaclassi. Alan Kay ha trovato questo design leggermente meno accattivante rispetto ai precedenti, quindi Smalltalk-74 è stato progettato con classi e ereditarietà basata su classi.

Dopo Smalltalk-74, Alan Kay sentì che Smalltalk si stava muovendo nella direzione sbagliata e non rappresentava in realtà ciò che OO era in realtà, e propose che il team abbandonasse Smalltalk e ricominciasse da capo, ma fu superato. Seguirono quindi Smalltalk-76, Smalltalk-80 (la prima versione di Smalltalk rilasciata ai ricercatori) e infine Smalltalk-80 V2.0 (la prima versione rilasciata commercialmente e la versione che divenne la base di ANSI Smalltalk) .

Poiché Simula-67 e Smalltalk-80 sono considerati i nonni di tutte le lingue OO, quasi tutte le lingue che seguirono, copiarono ciecamente il design delle classi e l'ereditarietà basata sulle classi. Un paio di anni dopo, quando altre idee come l'eredità basata sui mixin anziché sulle classi e la delega basata su oggetti invece dell'eredità basata sulle classi emerse, l'eredità basata sulle classi era già troppo radicata.

È interessante notare che l'attuale lingua di Alan Kay si basa sulla delega del prototipo.


"... la lingua corrente di Alan Kay ..." che è ...?
Javier,

@Javier: non credo che abbia un nome e il nome del sistema continui a cambiare.
Jörg W Mittag,

Questa dovrebbe essere una buona risposta per indicare la prossima volta che qualcuno elenca l'eredità come requisito per OO :)
Ehi,

1
@iceX: Alan Kay ha fondato il Viewpoints Research Institute per lavorare sulle sue idee. Sfortunatamente, le informazioni sono davvero sparse sul sito web.
Jörg W Mittag,

3
Citazione di Alan Kay su OO: "OOP per me significa solo messaggistica, conservazione e protezione locali e nascondere il processo statale, ed estremo vincolo tardivo di tutte le cose. Può essere fatto in Smalltalk e in LISP. Probabilmente ci sono altri sistemi in ciò è possibile, ma non ne sono consapevole. "
Joeri Sebrechts,

23

Molti programmatori preferiscono lavorare con le classi. È un concetto molto facile da capire che è un buon modello di processi di pensiero umano sul mondo (cioè, istintivamente mettiamo in relazione oggetti reali con il gruppo astratto di oggetti a cui li consideriamo appartenere, che è ciò che è una classe) . Inoltre, le classi semplificano il ragionamento sui tipi di oggetti: in un linguaggio basato su classi, applicare principi come la sostituzione di Liskov è più semplice di quanto non sia in un linguaggio in cui abbiamo solo oggetti che possono avere metodi diversi o il cui tipo può persino cambiare in fase di esecuzione , come nel caso di JavaScript.

Si noti che anche in JavaScript, un sacco di codice utilizza semplicemente la funzione prototipo per emulare le classi. Ciò è dovuto principalmente al fatto che molti programmatori preferiscono pensare in questo modo.

C'è anche un altro motivo per cui si preferiscono linguaggi basati su classi: è più facile compilarli in codice efficiente. Le VM JavaScript più efficienti creano in modo efficace classi per rappresentare i tipi di oggetti JavaScript mentre cambiano i loro metodi e prototipi. Vedi questa descrizione dell'implementazione di V8 per una logica sul perché ciò sia stato fatto.


4
Il tuo ultimo paragrafo supporta in realtà l'esatto contrario di ciò che stai dicendo: V8 dimostra che non hai bisogno di classi nella lingua per compilare un codice basato su classi efficiente.
Jörg W Mittag,

4
Sì, non ne hai bisogno, ma il fatto che V8 (e presumibilmente il Sé, anche se non ho letto molto sulla progettazione di quel sistema) crea effettivamente classi virtuali significa che partire da un linguaggio che usa nativamente le classi è quasi sicuramente più semplice, e quindi probabilmente finirebbe con la JIT che ha bisogno di dedicare meno tempo alla compilazione del codice.
Jules,

11
Certo, e il fatto che V8 crei effettivamente GOTOs e registri significa che rinunciare a tutte le astrazioni e scrivere direttamente nell'assemblaggio è quasi certamente più facile, e quindi probabilmente finirebbe con la JIT che ha bisogno di impiegare meno tempo a compilare il codice. È compito di un compilatore supportare astrazioni di livello superiore.
Jörg W Mittag,

1
Sì, ma è un compromesso, poiché l'astrazione di livello superiore è nella maggior parte dei casi più difficile da implementare e spesso ha una penalità di esecuzione in fase di esecuzione, soprattutto quando si lavora con un JIT piuttosto che un compilatore AOT. Sospetto che molti designer linguistici scelgano una struttura di classe per uno o entrambi questi motivi; So che è per questo che ho scelto classi con membri fissi per la lingua (altrimenti dinamica) su cui sto lavorando, ma posso solo speculare su altre lingue.
Jules,

1
Direi che l'unico modo in cui i programmatori preferiscono "pensare in classe" è perché è così che viene insegnata alla maggior parte di noi. Posso sicuramente ricordare molti dei miei compagni di college che hanno avuto difficoltà a cogliere e comprendere alcuni concetti orientati all'oggetto davvero fondamentali per diversi anni, però. Sembra solo ovvio e facile col senno di poi.
KChaloux,

3

Ho sentito che su grandi progetti, in cui team di persone lavorano insieme sullo stesso codice, che linguaggi flessibili (dove è possibile modificare le proprietà e i metodi di un oggetto durante il runtime) sono libertà che altri membri del team non ti vogliono avere.

Vogliono sapere, quando hanno a che fare con un oggetto, che l'oggetto agirà come dice il progetto, e non in un modo trasformato in cui un altro ambizioso sviluppatore ha deciso di cambiarlo per completare il proprio compito.

Quindi, l'unica ragione per cui posso concepire che qualcuno non vorrebbe la flessibilità offerta da questi fantastici linguaggi dinamici, è che vogliono semplificare lo sviluppo del team, il debug e la documentazione automatica.

Personalmente, ho sviluppato applicazioni in entrambe le metodologie e riesco a fare le cose molto più velocemente con i linguaggi dinamici. Non utilizzo nessuno di questi framework progettati per trasformare nuovamente il mio linguaggio dinamico in un linguaggio di classe. Queste cose sono una regressione per i miei gusti.


1

OOP per me significa solo messaggistica, conservazione locale, protezione e occultamento del processo statale ed estremo legame tardivo di tutte le cose - Alan Kay

Quindi quello che sta dicendo qui è che OO si occupa di creare scatole nere che rispondono ai messaggi. In un certo senso REST è il sistema OO definitivo in quanto utilizza verbi (cioè un messaggio) e risorse (ovvero una scatola opaca che contiene alcuni dati).

Quindi la domanda sul perché alcuni sono basati su classi e altri basati su prototipi non ha il punto che davvero non importa, sono entrambe semplici implementazioni. Un sistema che utilizza esclusivamente la messaggistica anziché le chiamate di metodo è altrettanto OO delle due istanze citate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.