Vantaggi e svantaggi della strutturazione di tutto il codice tramite classi e della compilazione in classi (come Java)


13

Modifica: la mia lingua consente l'ereditarietà multipla, a differenza di Java.

Ho iniziato a progettare e sviluppare il mio linguaggio di programmazione per scopi educativi, ricreativi e potenzialmente utili.

Inizialmente, ho deciso di basarlo su Java.

Ciò implicava che tutto il codice sarebbe stato scritto sotto forma di classi e che il codice fosse compilato in classi caricate dalla VM.

Tuttavia, ho escluso funzionalità come interfacce e classi astratte, perché non ne ho trovato bisogno. Sembrava applicare un paradigma e mi piacerebbe che la mia lingua non lo facesse. Volevo mantenere le lezioni come unità di compilazione, perché mi sembrava conveniente implementarle, familiari e mi piaceva l'idea.

Poi ho notato che sostanzialmente sono rimasto con un sistema di moduli, in cui le classi potevano essere usate come "spazi dei nomi", fornendo costanti e funzioni usando la staticdirettiva, o come modelli per oggetti che devono essere istanziati (scopo "effettivo" delle classi in altre lingue).

Ora mi chiedo: quali sono gli aspetti positivi e negativi di avere classi come unità di compilazione?

Inoltre, qualsiasi commento generale sul mio design sarebbe molto apprezzato. Un post informativo sulla mia lingua è disponibile qui: http://www.yannbane.com/2012/12/kava.html .


1
Se le classi includono anche spazi dei nomi che chiariscono tutti gli identificatori nella classe, allora hai un'unità di compilazione completamente autonoma. Quella classe può essere compilata correttamente, a condizione che tutte le dipendenze da altre classi possano essere soddisfatte dalla compilazione o dal riferimento a una classe compilata in un assembly. Tale atomicità dovrebbe avere evidenti vantaggi.
Robert Harvey,

Nota a margine: se rimuovi le classi e le interfacce astratte, stai forzando le persone a usare l'ereditarietà per il sottotipo e il polimorfismo. Questo è destinato a produrre un codice terribile. Inoltre, se non aggiungi l'ereditarietà multipla (e gestisci i problemi associati), è incredibilmente limitato.

1
@delnan: in realtà, puoi ancora usare la composizione per creare funzionalità.
Robert Harvey,

2
@RobertHarvey Suppongo che tu stia parlando di restrizioni per mancanza di eredità multipla. Sì, si può emularlo con una composizione sufficiente, ma difficilmente lo considero accettabile. Ad esempio, un oggetto che di solito implementerebbe due interfacce dovrebbe essere implementato due volte, in sottoclassi di classi base distinte (e mentre entrambe le implementazioni potrebbero delegare a una classe comune, è comunque un carico di codice extra e non puoi facilmente girare un'istanza dell'una in un'istanza dell'altra).

@delnan: Cosa c'è di sbagliato nell'usare l'ereditarietà per sottotipizzazione e polimorfismo? Ecco cos'è l'eredità per ...
Mason Wheeler,

Risposte:


6

quali sono i vantaggi di avere classi come unità di compilazione?

Può ridurre la complessità della lingua. Non sono necessari costrutti diversi, tutto viene trattato allo stesso modo. In alcuni progetti (anche se non il tuo sembra), trarrai vantaggio dal fatto di non avere statica e problemi di progettazione in cui tendono a incorrere (problemi di inizializzazione, limitazioni di concorrenza, disagio con generici / classi di tipi). Offre inoltre alcuni vantaggi del concetto di modulo come istanze di modulo isolate per sandboxing o parallelizzazione; e la digitazione dei moduli in cui le dipendenze si adattano a qualche interfaccia e l'intero valore del modulo di implementazione può essere istanziato e rilasciato.

Detto questo, il concetto tende ad avere più problemi che no. Realisticamente, non puoi trattare tutto allo stesso modo, poiché le classi di "livello superiore" hanno bisogno di regole speciali come avere un costruttore predefinito (oppure ti imbatti in problemi strani che li fanno girare). Anche la modularità delle unità di compilazione tende a diventare molto imbarazzante. In che modo una classe fa riferimento anche agli altri quando sono solo lezioni? Come vengono gestite quelle dipendenze e come si determina l'ordine corretto per lo sviluppo delle classi? Come ti assicuri che i riferimenti di classe duplicati vengano riutilizzati da diverse parti dell'app (o come gestisci le istanze duplicate se questa è la semantica che desideri)?

Dopo averlo esaminato, ho riscontrato molti problemi con le dipendenze, l'ambito di applicazione delle cose e le preoccupazioni di inizializzazione. Si finisce per imbattersi in problemi che rendono speciali le "classi di livello superiore" e molte limitazioni per farli funzionare che finiscono per modellarli in semplici spazi dei nomi.


Ho intenzione di avere una sola classe di massimo livello, la Object. Mi rendo conto che probabilmente avrò bisogno di un comportamento speciale per questo, ma fintanto che è un caso isolato, sto bene con quello. Tuttavia, non credo che avrò problemi di dipendenza. Esiste un insieme di classi che vengono caricate all'avvio della VM, alcune di esse sono implementate in modo nativo (la classe System), ma tutte ereditano da Object. Una volta che tutto è stato caricato, KVM carica la classe che è stato incaricato di caricare ed elabora le dipendenze. Tuttavia, sono interessato, quali problemi introducono la statica?
jcora,

@yannbane - Non intendo object, intendo le classi che si comportano come moduli piuttosto che come classi interne che non sono necessariamente pubbliche al di fuori della loro unità di compilazione. 'Risolve le dipendenze' si trasforma in un nido di calabroni giganti nei dettagli se si desidera qualsiasi tipo di comportamento in stile DLL; YMMV. Per quanto riguarda statico .
Telastyn,

Quel comportamento simile a un modulo sarebbe raggiunto attraverso l'uso di metodi / variabili statici, giusto? È male, invece di creare una classe che può essere istanziata, creare una classe che ha solo membri e metodi statici? Ho visto quell'articolo, tuttavia, non penso che si applichi ai membri statici costanti , né ai metodi statici. Ad esempio, non vedo nulla di male nella creazione di una Mathclasse, che in realtà è un modulo con metodi statici e chiamato un doppio membro statico costante Pi.
jcora,

@yannbane - No, non proprio. I moduli sono moduli perché sono istanziabili. Altrimenti hai solo spazi dei nomi in stile C ++. Una volta che limiti le tue classi di livello superiore ai namespace in stile C ++, non sono più classi.
Telastyn,

Hm, sto ancora bene e non vedo davvero il problema con la creazione di moduli con classi. E sì, i moduli fungono da spazi dei nomi, in particolare i moduli Python.
jcora,

4

Invece di rispondere a questa domanda, salirò di livello e suggerirò di studiare MIT OpenCourseWare , in particolare 6.035 (Computer Language Engineering). Questo spiegherà l'intera problematica, in modo da non essere tentato di porre di nuovo domande come questa.

Ingegneria del linguaggio informatico

L'unico prerequisito è Java.

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-035-computer-language-engineering-spring-2010/lecture-notes/

descrizione del corso

Questo corso analizza i problemi associati all'implementazione di linguaggi di programmazione di livello superiore. Gli argomenti trattati comprendono: concetti, funzioni e strutture fondamentali dei compilatori, interazione di teoria e pratica e utilizzo di strumenti nella creazione di software. Il corso include un progetto multi-persona sulla progettazione e l'implementazione del compilatore.

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.