Definizione formale per il termine "linguaggio OO puro"?


13

Non riesco a pensare a un posto migliore tra i fratelli SO per porre una domanda del genere. Inizialmente volevo chiedere "Python è un linguaggio OO puro?" ma considerando i problemi e una sorta di disagio che le persone sperimentano mentre provano a definire il termine, ho deciso di iniziare con l'ottenere una definizione chiara per il termine stesso.

Sarebbe piuttosto giusto iniziare con la corrispondenza del Dr. Alan Kay, che ha coniato il termine (notare l'ispirazione nell'analogia biologica con le cellule o altri oggetti viventi).

Esistono i seguenti modi per affrontare l'attività:

  1. Fornisci un'analisi comparativa elencando i linguaggi di programmazione che possono mostrare (o non riuscire a farlo) determinate proprietà uniche e sufficienti per definire il termine (sebbene Smalltalk, Scala, Java e così via) siano possibili esempi ma IMO in questo modo sembra né realmente completo né fruttuoso )
  2. Fornisci una definizione formale (o vicino ad essa, ad esempio in uno stile più accademico o matematico).
  3. Fornisci una definizione filosofica che si baserebbe totalmente sul contesto semantico del linguaggio concreto o sull'esperienza di programmazione a priori (ci deve essere qualche possibilità di spiegazione riuscita da parte della comunità).

La mia versione attuale: "Se un certo linguaggio di programmazione ( formale ) che può ( grammaticalmente ) distinguere tra operazioni e operandi, nonché inferire sul tipo di ciascun operando se questo tipo è un oggetto (nel senso di OOP) o no, allora chiamiamo una tale lingua una lingua OO fintanto che esiste almeno un tipo in questa lingua che è un oggetto. Infine, se tutti i tipi di lingua sono anche oggetti, definiamo tale linguaggio come linguaggio OO puro (forte) ".

Gradirei ogni possibile miglioramento. Come puoi vedere, ho appena reso la definizione dipendente dal termine "oggetto" (spesso definito come classe di oggetti).

[MODIFICARE]

Inoltre, io uso (per fortuna ben compreso) la nozione di un tipo come nelle lingue tipizzate. La programmazione dei tipi di dati o la programmazione orientata ai tipi non è solo un'interpretazione sintattica (del testo del programma, ovvero come trattare determinati valori letterali e variabili di dati - qualcosa che si evolve in sicurezza dei tipi) ma può essere attribuita alla grammatica del linguaggio e studiata in modo formale (usando la logica matematica) come i cosiddetti sistemi di tipo . Si noti che richiedere un particolare sistema di tipi per avere un cosiddetto tipo universale è uno dei modi per definire la purezza del linguaggio OO (ci sono modi per espanderlo semanticamente).

NB

come rispondere :

  • aiuta se specifichi un libro o un riferimento che supporti / spieghi la tua comprensione della terminologia e dei concetti (di solito una buona definizione copre o fa riferimento a tutti i concetti dipendenti eccetto quelli elementari).
  • se possibile, indicare una categoria rientrata della risposta / definizione se non è chiaro diversamente (vedi sopra: 1 - per esempio di linguaggio, 2 - logica matematica, 3 - descrizione tecnica e filosofia di programmazione)
  • la classificazione è importante (e anche perché il termine OO puro è incluso nel termine OO) mentre si risponde al tentativo di mescolare elementi del paradigma OO da altre metodologie ben note (e non confonderli / sovrapporli in alcun modo, ad es. in genere è possibile coprire elementi di programmazione modulare / incarnato con la programmazione OO): provare a distinguere OOP da (incluso o essere parte di) Programmazione funzionale, Programmazione logica (specialmente fortemente specializzata), Tipi di dati Abstarct (ADT), Modulare, Metaprogrammazione (generici e tempo di macroespansione di LISP), Contratti (ad es. Eiffel), Aspect-oriented (AO), (la differenza tra la classificazione dichiarativa e funzionale e le definizioni storiche della struttura strutturata di Dijkstra sono chiare)

sulla difficoltà di dare una definizione formale : abbastanza sorprendentemente è molto facile dare una descrizione matematica di OOP in forma di un certo sistema logico (formale) (molto probabilmente basato sul tipo) e definire un concetto dopo l'altro. Si può anche cercare di fare qualcosa di più pratico per l'applicazione di tale formalismo per il controllo di sicurezza di tipo o nuovi aspetti progettuali lingua che meramente astratto divertimento o esercizio fisico (anche la formulazione di ricerca di programmazione orientata agli oggetti in intuizionistica Tipo Theory , tipi dipendenti , in modo indipendente, in formalismi FOL come lambda calcolo e semplicemente usando la teoria delle categorie). Un punto principale qui è che non sorprendetali formulazioni IMO sono fortemente distorte (imperfette) dalla molto probabilmente inizialmente incompleta comprensione di OOP (in ingegneria informatica) e finiscono per essere quasi inaccessibili in seguito (contribuendo così a malapena al mondo della programmazione - forse tranne che una certa percentuale trova applicazioni indietro dal mondo formale essendo integrato nelle lingue popolari ).

Quindi sì, è difficile dare esattamente una "buona" definizione, non solo una definizione. Ma sono sicuro di averlo chiesto qui a causa della tua esperienza e coinvolgimento diretto, ragazzi.


2
Bene, ti sei risposto per Python. "No".
psr

2
+1 per la bella domanda, ma la tua versione è un po 'imperfetta dal problema che un tipo e un oggetto sono cose diverse.
Frank,

5
@JoachimSauer: In un'altra mail sulla mailing list di Squeak ha detto che "la grande idea è la messaggistica" e che si rammarica di averla mai definita "orientata agli oggetti" e che avrebbe dovuto piuttosto chiamarla "orientata ai messaggi". Erlang, ad esempio, è un linguaggio completamente orientato agli oggetti che soddisfa tutti i criteri del Dr. Kay senza avere alcun concetto di "oggetti", "metodi", "eredità", "classi", "prototipi" o qualcosa del genere .
Jörg W Mittag,

1
Questa potrebbe essere una buona illustrazione del fatto che le sintassi non sono sufficienti per definire un linguaggio OO. Se si può dimostrare che OOP (ad esempio come strumento) è solo semantico (indipendente dalla sintassi), ciò cambia (inverte) completamente la mia domanda!
Yauhen Yakimovich,

2
@YauhenYakimovich Questo è uno dei problemi alla radice nella discussione di OOP, ognuno e il suo cane hanno la loro idea di cosa sia. Al contrario, la programmazione strutturata e la programmazione funzionale possono essere definite in modo molto semplice. Questo mi porta a chiedermi se OO abbia proprietà simili alla religione anziché alla scienza.
Ricky Clarkson,

Risposte:


19

OO, secondo Alan Kay è tutto sulla trasmissione dei messaggi, e basta. Vedrai che qualità come il polimorfismo e l'incapsulamento sono in realtà derivati ​​dal passaggio di messaggi.

Ora quella posizione è in effetti molto estrema, perché in sostanza significa che solo Smalltalk e le lingue si qualificherebbero.

Penso che tu possa definire OO come costruire il tuo sistema su entità, che incapsulano completamente il loro stato e che sono rese scambiabili a causa delle loro intrinseche qualità polimorfiche. Si potrebbe quindi sostenere che un linguaggio puramente OO garantisce che queste due qualità fondamentali siano sempre soddisfatte. Ciò che rende le lingue OO "impure" sarebbero meccanismi che consentono la creazione di costrutti che non soddisfano questi criteri, come la possibilità di:

  • dichiarare campi pubblici
  • dichiarare variabili che possono contenere solo istanze di una classe specifica e delle sue sottoclassi (vale a dire che le variabili devono essere tipizzate rispetto alle interfacce, che è ciò attraverso cui gli oggetti biologici comunicano nell'anologia di Kay), che viene reso ancora più stretto se la classe in questione è definitiva, come che lascia ancora meno spazio al polimorfismo
  • dichiarare i primitivi

Inoltre, la purezza del linguaggio IMHO è più una debolezza che una forza. OO non è un proiettile d'argento. Nessun singolo paradigma è.


2
+1 per "OO non è un proiettile d'argento".
Andres F.

1
@AndresF. Si noti che il valore pratico di OOP e altre conoscenze teoriche relative alla programmazione non fanno realmente parte di una domanda. È abbastanza ovvio che uno può scrivere il codice in un modo abbastanza efficace senza alcuna profonda conoscenza delle tecniche di programmazione o delle teorie (e viceversa). Né vengono discusse le proprietà dell'applicazione delle lingue OO, ecc.
Yauhen Yakimovich,

@YauhenYakimovich Oh, lo so. Non avrei annullato la risposta se fosse stata fuori tema. Tuttavia, mi è piaciuta un'affermazione con cui sono d'accordo.
Andres F.,

@AndresF. Certo :-) "OO non è un proiettile d'argento" è probabilmente vero così come a noi manca un linguaggio di programmazione perfetto. Ma cosa rende OOP esattamente un proiettile d'argento? Proprio come una buona segnalazione di bug, penso che una terminologia dettagliata e precisa sia il modo di rispondere a questo. Ho investito così tanto tempo a lavorarci che sono solo dannatamente curioso di portarlo al livello successivo. OOP è solo un mucchio di idee copiate da un libro di programmazione a un altro?
Yauhen Yakimovich,

@ back2dos +1 per indicare esplicitamente il ruolo del "passaggio di messaggi" secondo Kay (Smalltalk, Objective-C). Apparentemente non ha mai avuto intenzione di vedere OOP sviluppato verso le direzioni che ha oggi. Ma mi è davvero piaciuto che Kay avesse quelle idee per rendere gli oggetti NON dati (tipi). Ha davvero spinto ad attribuire loro qualità biologiche, ma è finito in "messaggistica".
Yauhen Yakimovich,

6

Mi avvicinerei a questo definendolo come un linguaggio che utilizza costrutti OOP e nient'altro (allo stesso modo in cui un linguaggio FP puro utilizza funzioni pure con dati immutabili e nient'altro).

In particolare:

  • Ogni entità su cui opera il tuo programma è un oggetto di prima classe , ovvero senza primitive, senza puntatori, senza array, ecc.
  • L'unica cosa che puoi fare con un oggetto è chiamare un metodo (potenzialmente polimorfico) su di esso (== invio di un messaggio). Non esistono altre operazioni.
  • Tutti i dati sono incapsulati - cioè nessun accesso al campo pubblico, è necessario passare tramite metodi su un oggetto
  • Se hai funzioni di prima classe, devono essere anche oggetti , quindi dovresti fare qualcosa del generefunctionObject.call(param1,param2)
  • Nessuna variabile globale : se si desidera qualcosa del genere, è necessario utilizzare un oggetto per rappresentare l'ambiente globale corrente, ad esempio environment.getValue("myThing")o inserire la variabile in un oggetto di classe

Nota che questo lascia ancora aperte alcune opzioni:

  • Modelli di oggetti basati su classi e basati su prototipi
  • Come viene implementata l'ereditarietà (se non del tutto)
  • Se hai metodi di spedizione singoli o multipli
  • Se i tuoi oggetti sono digitati staticamente o dinamicamente
  • La sintassi esatta utilizzata per le chiamate al metodo (ad es. Potresti avere dello zucchero sintattico per getter / setter ecc.)

1
queste sono buone definizioni, ma non confondere la realtà dell'oggetto con la semplice sintassi. Solo perché le funzioni e le variabili globali hanno una sintassi amichevole, possono in realtà essere oggetti a cuore.
Ddyer,

@ddyer - è corretto se è veramente solo sintassi, ma penso che se la sintassi introduce anche una semantica diversa, allora può spezzare la "purezza". Ad esempio, wrt variabili globali l'uso di globalVariableNameper accedere a una variabile globale è una semantica diversa da una chiamata di metodo su un oggetto, che sarebbe l'unico modo per accedere a un valore non locale in OOP puro.
Mikera,

Penso che "Tutto" debba essere qualificato. Se un linguaggio non ha alcuna capacità riflessiva (ad esempio, non può fare riferimento a un metodo di un oggetto con un nome astratto o memorizzarlo in una variabile), allora anche i metodi devono essere oggetti? I riferimenti sono oggetti? Riferimenti e oggetti sono anche cose diverse?
Joachim Sauer,

@Joachim - buon punto. L'ho qualificato come "ogni entità su cui opera il tuo programma" al fine di distinguere gli oggetti dai metaoggetti nel linguaggio come nomi di variabili e costrutti sintattici. Ovviamente se il tuo programma opera effettivamente su tali cose attraverso la riflessione, allora dovrebbero essere reificati come oggetti reali, ma ciò non sarà sempre un requisito. Comunque, se riesci a pensare a una qualifica migliore, allora sentiti libero di modificarlo!
Mikera,

"Modelli di oggetti basati su classi e basati su prototipi": ma direi che in entrambi i casi hai una sorta di classificazione, cioè raggruppa oggetti con una struttura e un comportamento comuni.
Giorgio,

4

La discussione sui cosiddetti linguaggi OO è sempre stata un po 'complicata. Vale a dire:

"Qualcuno mi ha detto che la lingua X è OO, quindi quindi la lingua X è uguale a OO, quindi ogni lingua che non ha le caratteristiche della lingua X non può essere OO. E poiché sto scrivendo il mio codice nella lingua X, tutto ciò che faccio è OO. "

Il termine design orientato agli oggetti si riduce a 3 cose:

  1. Design modulare con oggetti autonomi che non conoscono informazioni inutili sul resto del programma, ovvero l' accoppiamento più lento possibile.
  2. Incapsulamento dei dati all'interno degli oggetti per impedire l'accesso esterno, sia intenzionale che accidentale.
  3. Dipendenze chiaramente specificate tra gli oggetti. Per ottenere un accoppiamento lento, ma anche per facilitare la manutenzione e l'espansione del programma.

1) è puro design del programma, può essere realizzato in qualsiasi linguaggio di programmazione. Tuttavia, alcune lingue hanno utili funzioni come class / struct e parole chiave private.

2) è principalmente la progettazione di programmi, sebbene non possa essere pienamente realizzata senza il supporto linguistico, poiché sono necessari meccanismi linguistici come privato / statico per proteggersi dall'uso accidentale.

3) è principalmente design del programma. Esistono in genere tre diverse dipendenze: "l'oggetto X contiene l'oggetto Y", "l'oggetto X è un tipo di Y" e "l'oggetto X interagisce con l'oggetto Y". Ci sono molte caratteristiche del linguaggio per aiutare con queste dipendenze: eredità / polimorfismo, classi di base astratte e così via.

Ora, se guardiamo a quanto sopra, possiamo vedere che a malapena hai bisogno di funzionalità linguistiche per scrivere programmi OO. Le funzionalità lo rendono molto più semplice.

I suddetti obiettivi non possono essere raggiunti utilizzando una logica fangosa all'indietro: solo perché usi la parola chiave class, il tuo programma non ottiene automaticamente un design modulare. Solo perché usi l'ereditarietà, ciò non significa automaticamente che le dipendenze degli oggetti abbiano un senso. Un linguaggio con funzionalità OO consentirebbe comunque cose come class TheWholeBloodyProgram"Animale eredita il gatto".

Purtroppo, l'argomento della buona progettazione di programmi orientati agli oggetti viene raramente menzionato in questo tipo di discussioni. I programmatori di lavaggio del cervello guardano solo la sintassi e yap cose come ad esempio "C ++ ha tipi di dati primitivi, quindi il tuo programma C ++ non è OO", poi vanno a scrivere un programma orribile nella loro lingua preferita, senza usare alcun accenno di programma di progettazione quantomeno.

Per rispondere alla domanda: pochissime, se qualche lingua ha il supporto per la corretta progettazione del programma OO. Scoprire quali lingue che hanno determinate funzionalità relative a OO è irrilevante purché il programmatore non sappia cosa significhi design orientato agli oggetti. Un programmatore che afferma che alcune lingue sono orientate agli oggetti non ha probabilmente compreso il concetto di OO nel suo insieme. Chiedi all'aspirante programmatore OO come progettano i programmi OO. Se la prima cosa che fanno è iniziare a urlare parole chiave in lingua, allora puoi tranquillamente presumere che non conoscano il design OO.

Forse esiste qualche elaborato strumento di alto livello UML molto al di sopra del codice sorgente grezzo, che impone al programmatore di scrivere solo programmi con un buon design orientato agli oggetti, ma ne dubito. I migliori strumenti di progettazione per la programmazione OO sono probabilmente ancora il cervello umano e il buon senso.


Puoi chiarire in che modo differisce la tua definizione, ad esempio la programmazione modulare con tipi di dati astratti? Penso che tu sia sulla buona strada, ma non riesco ancora a vedere il treno!
Jörg W Mittag,

@ JörgWMittag Non è necessariamente diverso, ADT tradizionale: s può essere scritto usando un design orientato agli oggetti, con incapsulamento, setter / getter, modi per ereditarlo, ecc. Ecc. Ma possono anche essere scritti senza riguardo al design OO. ->

2
@ JörgWMittag Se ad esempio hai un linguaggio come C, con supporto linguistico limitato per OO, è difficile scrivere ADT: s in modo orientato agli oggetti. L'errore più comune è lasciare l'allocazione dell'ADT al chiamante, ovvero dare loro una struttura pubblica con tutti gli interni esposti, interrompendo l'incapsulamento. Il modo corretto di farlo in C è attraverso i cosiddetti "tipi opachi" (tipi incompleti), anche se non molti programmatori C sanno usarli.

@Lundin: Nel documento pubblicato da JörgWMittag come commento a un'altra risposta c'è un interessante confronto (IMO) tra ADT e OO.
Giorgio,

Ricordo da alcuni libri UML (probabilmente) un ulteriore punto 0. Astrattezza (sottolineando l'importanza della formulazione astratta essenziale per le relazioni tra oggetti come polimorfismo, eredità, aggregazione, ecc.).
Yauhen Yakimovich,

2

No, non esiste una definizione formale o utile, e non ci sarà mai. Per alcune persone, OOP significa "Classe di base universale" e "Deve usare la semantica di riferimento, meglio con un garbage collector" - e puoi persino ottenere cavilli sulla sintassi, una delle cose meno rilevanti mai inventate.

Alla fine, prima di tutto, devi rispondere alla domanda "Che cos'è un oggetto?". I più ristretti insisteranno per ereditare da qualche inutile classe di base universale e inutilmente essere assegnati a un bidone della spazzatura per qualificarsi. Ma preferisco una definizione molto più utile. Lo scopo di OOP è disporre di alcuni dati e di alcune funzioni che è possibile richiamare su tali dati. Così

  • Un oggetto contiene un certo stato e offre alcune funzioni su quello stato.

In questo caso, si intqualifica anche . Dopotutto, quando scrivi il codice modello in C ++ che può accettare sia le primitive che gli oggetti, allora diventa difficile sostenere che le primitive sono diverse in modo sostanziale. Non c'è nulla di significativamente diverso al Vector v1, v2; v1 + v2;posto di int v1, v2; v1 + v2;(tranne la semantica scadente di inizializzazione, bisogna ammetterlo). Inoltre, questo permette a lambda e cose del genere di essere oggetti, mentre mantengono lo stato - le loro catture - e offrono una funzione su quello stato, per chiamare lambda.

Fortunatamente, possiamo anche classificare i puntatori a funzioni libere come oggetti, poiché entrambi mantengono lo stato (un indirizzo) e una funzione su quello stato (per chiamarlo). Quindi dovrebbe essere consentita una funzione libera, anche se dovessi dire che tutte le funzioni libere sono in realtà puntatori di funzioni globali.


2
Non vedo la necessità di una tale distinzione. Ma in secondo luogo, hanno la stessa identità di qualsiasi altro oggetto ha un confronto indirizzo / riferimento. Il fatto che non sia possibile distinguere due oggetti con lo stesso stato, tranne confrontando gli indirizzi, è tutt'altro che nuovo e si applica a tutti gli oggetti.
DeadMG

5
-1. Inizia con uno sfogo inutile e inutile, passa rapidamente all'attacco ad hominem e l'unica cosa persino lontanamente fattuale (la definizione di OOP ) è sbagliata. Leggere Informazioni sull'astrazione dei dati, rivisitato da William R. Cook per la differenza tra un tipo di dati astratto e un oggetto.
Jörg W Mittag,

1
"Non vedo la necessità di una tale distinzione". Ma questa distinzione è tra le caratteristiche comunemente accettate degli oggetti. Naturalmente, puoi sviluppare la tua nozione di un oggetto che è diverso da ciò che è comunemente accettato. Sei totalmente libero di farlo.
Giorgio,

2
@ Jörg Mi permetto di dissentire. Non sono completamente d'accordo con questo post, ma chiamare l'avvertimento nel primo paragrafo "inutile" o un "sfogo" è disonesto. Non esiste una definizione universalmente concordata per OOP. Questo è un fatto semplice e ampiamente riconosciuto. Il resto del post è una definizione di OOP. Certamente non il più ampiamente usato, né quello che darei, ma, come diceva DeadMG, in realtà abbastanza utile.
Konrad Rudolph,

2
@KonradRudolph: quel paragrafo è stato letto in modo molto diverso quando ho scritto il mio commento, anche confrontando i programmatori che si preoccupano della sintassi con i razzisti, menzionando persino un utente specifico di questo sito per nome.
Jörg W Mittag,

0

Puoi pensarci con un esempio negativo. Java non è un linguaggio orientato agli oggetti puro perché esistono anche tipi primitivi che non sono oggetti. Questi sono numeri interi, doppi, array e così via. In un linguaggio di oggetti puro, la semantica degli oggetti è disponibile per tutto.

C'è anche la questione di quanta parte del linguaggio sia chiusa alla modifica, anche all'interno della struttura degli oggetti. In Java non è possibile definire nuove sottoclassi per alcune classi, come String o Class.

Quali lingue sono pure? L'unico candidato che viene in mente è smalltalk.


Anche Ruby non è un linguaggio OO puro?
zxcdw,

2
@zxcdw (e ddyer): questo è esattamente il problema: nessuno ha una definizione formale di "OO puro", quindi nessuno può dare una risposta definitiva a quella domanda.
Joachim Sauer,
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.