Définition formelle du terme «langage OO pur»?

13

Je ne peux pas penser à un meilleur endroit parmi les frères et sœurs SO pour poser une telle question. À l'origine, je voulais demander "Le python est-il un pur langage OO?" mais compte tenu des problèmes et de l'inconfort que ressentent les gens en essayant de définir le terme, j'ai décidé de commencer par obtenir une définition claire du terme lui-même.

Il serait plutôt juste de commencer par la correspondance du Dr Alan Kay, qui a inventé le terme (notez l'inspiration dans l'analogie biologique avec les cellules ou d'autres objets vivants).

Il existe différentes façons d'aborder la tâche:

  1. Donnez une analyse comparative en répertoriant les langages de programmation qui peuvent présenter (ou ne pas le faire) certaines propriétés uniques et suffisantes pour définir le terme (bien que Smalltalk, Scala, Java , etc.) sont des exemples possibles mais IMO de cette façon ne semble ni vraiment complet ni fructueux )
  2. Donnez une définition formelle (ou proche d'elle, par exemple dans un style plus académique ou mathématique).
  3. Donnez une définition philosophique qui dépendrait totalement du contexte sémantique d'un langage concret ou d'une expérience de programmation a priori (il doit y avoir une chance d'explication réussie par la communauté).

Ma version actuelle: "Si un certain langage de programmation ( formel ) qui peut ( grammaticalement ) faire la différence entre les opérations et les opérandes ainsi que déduire du type de chaque opérande si ce type est un objet (au sens de la POO) ou non, alors nous appelons un tel langage est un langage OO tant qu'il y a au moins un type dans ce langage qui est un objet. Enfin, si tous les types de langage sont également des objets, nous définissons ce langage comme étant un langage OO pur (fort). "

J'apprécierais toute amélioration possible de celui-ci. Comme vous pouvez le voir, je viens de rendre la définition dépendante du terme "objet" (souvent entièrement référencé comme classe d'objets).

[ÉDITER]

De plus, j'utilise (heureusement bien compris) la notion de type comme dans les langages typés. La programmation de type de données ou la programmation orientée type n'est pas seulement une interprétation syntaxique (du texte du programme, c'est-à-dire comment traiter certaines valeurs des littéraux et des variables de données - quelque chose qui évolue en sécurité de type) mais peut être attribuée à la grammaire du langage et étudiée de manière formelle (en utilisant la logique mathématique) en tant que systèmes dits . Notez que l'exigence d'un système de type particulier d'avoir un type dit universel est l'une des façons de définir la pureté du langage OO (il existe des moyens de l'étendre sémantiquement).

NB

comment répondre :

  • cela aide si vous spécifiez un livre ou une référence qui soutient / explique votre compréhension de la terminologie et des concepts (généralement une bonne définition couvre ou fait référence à tous les concepts dépendants sauf élémentaire).
  • si possible, indiquez une catégorie en retrait de votre réponse / définition si ce n'est pas clair autrement (voir ci-dessus: 1 - par exemple de langage, 2 - logique mathématique, 3 - description technique et philosophie de programmation)
  • la classification est importante (et aussi parce que le terme pure-OO est inclus dans le terme OO) tout en répondant, essayez de démêler les éléments du paradigme OO d'autres méthodologies bien connues (et en aucun cas les confondre / les chevaucher, par exemple, typiquement, des éléments de programmation modulaire peuvent être couverts / incorporé à la programmation OO): essayer de distinguer la POO de (incluant ou faisant partie de) la programmation fonctionnelle, la programmation logique (particulièrement fortement spécialisée), les types de données Abstarct (ADT), modulaire, la métaprogrammation (génériques et macro-expansion de LISP), Contrats (par exemple Eiffel), orientés aspect (AO), (la différence entre la classification déclarative et fonctionnelle ainsi que les définitions historiques de la structure de Dijkstra sont claires)

sur la difficulté de donner une définition formelle : assez étonnamment, il est très facile de donner une description mathématique de la POO sous la forme d'un certain système logique (formel) (très probablement basé sur le type) et de définir un concept après l'autre. On peut même essayer de faire quelque chose de plus pratique en appliquant ce formalisme à la vérification de la sécurité du type ou à de nouveaux aspects de conception de langage que simplement un divertissement abstraitou un exercice (également formulation de recherche de POO dans la théorie des types intuitionistes , types dépendants , indépendamment, dans les formalismes FOL comme le calcul lambda et juste en utilisant la théorie des catégories). Un point principal ici est que sans surpriseces formulations OMI sont fortement biaisées (défectueuses) par une compréhension très probablement initialement incomplète de la POO (en ingénierie informatique) et finissent par être presque inaccessibles par la suite (contribuant ainsi à peine à l'arrière du monde de la programmation - peut-être qu'un certain pourcentage trouve des applications de retour du monde formel en étant intégré dans les langues populaires ).

Alors oui, il est difficile de donner exactement une "bonne" définition, pas seulement une définition. Mais je suis certain de poser cette question ici en raison de votre expérience et de votre implication directe, les gars.

Yauhen Yakimovich
la source
2
Eh bien, vous vous êtes répondu pour Python. "Non".
psr
2
+1 pour la bonne question, mais votre version est un peu défectueuse par le problème qu'un type et un objet sont des choses différentes.
Frank
5
@JoachimSauer: Il a déclaré dans un autre courrier sur la liste de diffusion Squeak que "la grande idée est la messagerie" et qu'il regrette de l'avoir appelé "orienté objet" et aurait plutôt préféré l'appeler "orienté message" à la place. Erlang, par exemple, est un langage complètement orienté objet qui répond à tous les critères du Dr Kay sans avoir aucun concept des "objets", "méthodes", "héritage", "classes", "prototypes" ou quelque chose comme ça .
Jörg W Mittag
1
Cela pourrait être une belle illustration que les syntaxes ne suffisent pas pour définir un langage OO. Si l'on peut montrer que la POO (par exemple en tant qu'outil) est uniquement sémantique (indépendante des syntaxes), cela change (inverse) complètement ma question!
Yauhen Yakimovich
2
@YauhenYakimovich C'est l'un des problèmes fondamentaux de la discussion sur la POO, chacun et son chien ont leur propre idée de ce que c'est. En revanche, la programmation structurée et la programmation fonctionnelle peuvent chacune être définies très simplement. Cela m'amène à me demander si OO a des propriétés similaires à la religion plutôt qu'à la science.
Ricky Clarkson

Réponses:

19

OO, selon Alan Kay, tout est question de transmission de messages, et c'est tout. Vous verrez que des qualités telles que le polymorphisme et l'encapsulation sont en fait dérivées du passage de messages.

Maintenant, cette position est en fait très extrême, car cela signifie essentiellement que seuls Smalltalk et les langues seraient admissibles.

Je pense que vous pouvez définir OO comme la construction de votre système sur des entités qui encapsulent pleinement leur état et qui sont rendues échangeables en raison de leurs qualités polymorphes inhérentes. On pourrait donc soutenir qu'un langage purement OO garantit que ces deux qualités fondamentales sont toujours respectées. Ce qui rend les langages OO "impurs" serait des mécanismes qui permettent la création de constructions qui ne répondent pas à ces critères, comme les possibilités de:

  • déclarer des champs publics
  • déclarer des variables qui ne peuvent contenir que des instances d'une classe spécifique et de ses sous-classes (c'est-à-dire que les variables doivent être typées par rapport aux interfaces, ce que les objets biologiques communiquent par le biais de l'anologie de Kay), ce qui est rendu encore plus étroit si la classe en question est finale, comme qui laisse encore moins de place au polymorphisme
  • déclarer des primitives

Là encore, la pureté du langage IMHO est plus une faiblesse qu'une force. OO n'est pas une solution miracle. Aucun paradigme n'est.

back2dos
la source
2
+1 pour "OO n'est pas une solution miracle".
Andres F.
1
@AndresF. Notez que la valeur pratique de la POO ainsi que d'autres connaissances théoriques liées à la programmation ne fait pas vraiment partie d'une question. Il est assez évident que l'on peut écrire du code d'une manière assez réussie sans aucune compréhension approfondie des techniques de programmation ou des théories (et vice versa). Ni les propriétés d'application des langages OO ne sont discutées, etc.
Yauhen Yakimovich
@YauhenYakimovich Oh, je sais. Je n'aurais pas voté pour la réponse si elle avait été hors sujet. Pourtant, j'ai aimé une affirmation avec laquelle je suis d'accord.
Andres F.
@AndresF. Bien sûr :-) "OO n'est pas une solution miracle" est très probablement vrai ainsi que nous manquant d'un langage de programmation parfait. Mais qu'est-ce qui fait que la POO n'est pas une solution miracle? Tout comme un bon rapport de bogue, je pense qu'une terminologie détaillée et précise est le moyen d'y répondre. J'ai investi tellement de temps à travailler avec lui que je suis juste sacrément curieux de l'amener au niveau supérieur. La POO est-elle juste un tas d'idées copiées d'un livre de programmation à un autre?
Yauhen Yakimovich
@ back2dos +1 pour avoir explicitement souligné le rôle du "passage de message" selon Kay (Smalltalk, Objective-C). Apparemment, il n'a jamais eu l'intention de voir la POO évoluer vers les directions qu'elle a aujourd'hui. Mais j'ai vraiment aimé que Kay ait eu ces idées pour faire des objets PAS des données (types). Il a vraiment poussé à leur attribuer des qualités biologiques, mais s'est retrouvé dans la "messagerie".
Yauhen Yakimovich
6

J'aborderais cela en le définissant comme un langage qui utilise des constructions OOP et rien d'autre (de la même manière qu'un langage FP pur utilise des fonctions pures avec des données immuables et rien d'autre).

En particulier:

  • Chaque entité sur laquelle votre programme fonctionne est un objet de première classe - c'est-à-dire pas de primitives, pas de pointeurs, pas de tableaux, etc.
  • La seule chose que vous pouvez faire avec un objet est d'appeler une méthode (potentiellement polymorphe) dessus (== envoyer un message). Aucune autre opération n'existe.
  • Toutes les données sont encapsulées - c'est-à-dire pas d'accès au champ public, vous devez passer par des méthodes sur un objet
  • Si vous avez des fonctions de première classe, elles doivent également être des objets - vous devrez donc faire quelque chose commefunctionObject.call(param1,param2)
  • Pas de variables globales - si vous voulez quelque chose comme ça, vous devrez utiliser un objet pour représenter l'environnement global actuel, par exemple environment.getValue("myThing")ou mettre la variable dans un objet de classe

Notez que cela laisse encore pas mal d'options ouvertes:

  • Modèles d'objets basés sur des classes ou basés sur des prototypes
  • Comment l'héritage est mis en œuvre (le cas échéant)
  • Que vous ayez une expédition unique ou multiple sur les méthodes
  • Que vos objets soient typés de manière statique ou dynamique
  • La syntaxe exacte utilisée pour les appels de méthode (par exemple, vous pouvez avoir du sucre syntaxique pour les getters / setters, etc.)
mikera
la source
1
ce sont de bonnes définitions, mais ne confondez pas la réalité des objets avec une simple syntaxe. Tout simplement parce que les fonctions et les variables globales ont une syntaxe conviviale, elles peuvent en fait être des objets au cœur.
ddyer
@ddyer - c'est correct s'il ne s'agit vraiment que de syntaxe, mais je pense que si la syntaxe introduit également des sémantiques différentes, elle peut briser la "pureté". Par exemple, wrt variables globales à utiliser globalVariableNamepour accéder à une variable globale est une sémantique différente d'un appel de méthode sur un objet, ce qui serait le seul moyen d'accéder à une valeur non locale en pure POO.
mikera
Je pense que "Tout" doit être qualifié. Si un langage n'a aucune capacité de réflexion (par exemple, il ne peut pas référencer une méthode d'un objet par un nom abstrait ou le stocker dans une variable), les méthodes doivent-elles également être des objets? Les références sont-elles des objets? Les références et les objets sont-ils même des choses différentes?
Joachim Sauer
@Joachim - bon point. Je l'ai qualifié de "chaque entité sur laquelle votre programme fonctionne" afin de distinguer les objets des méta-objets dans le langage comme les noms de variables et les constructions syntaxiques. De toute évidence, si votre programme fonctionne réellement sur de telles choses via la réflexion, elles devraient être réifiées en tant qu'objets réels, mais cela ne sera pas toujours une exigence. Quoi qu'il en soit, si vous pouvez penser à une meilleure qualification, n'hésitez pas à la modifier!
mikera
"Modèles d'objets basés sur des classes ou basés sur des prototypes": mais je dirais que dans les deux cas, vous avez une sorte de classification, c'est-à-dire que vous regroupez des objets ayant une structure et un comportement communs.
Giorgio
4

La discussion sur les soi-disant langues OO a toujours été un peu lavée par le cerveau. C'est à dire:

"Quelqu'un m'a dit que la langue X est OO, donc la langue X est égale à OO, alors chaque langue qui n'a pas les fonctionnalités de la langue X ne peut pas être OO. Et parce que j'écris mon code dans la langue X, tout ce que je fais est OO. "

Le terme conception orientée objet se résume à 3 choses:

  1. Conception modulaire avec des objets autonomes qui ne connaissent pas les informations inutiles sur le reste du programme, aussi couplage lâche que possible.
  2. Encapsulation des données à l'intérieur des objets pour empêcher l'accès externe, à la fois intentionnel et accidentel.
  3. Dépendances clairement spécifiées entre les objets. Pour obtenir un couplage lâche, mais aussi pour faciliter la maintenance et l'expansion du programme.

1) est une conception de programme pure, il peut être réalisé dans n'importe quel langage de programmation. Cependant, certaines langues ont des fonctionnalités utiles telles que class / struct et des mots-clés privés.

2) est principalement la conception de programmes, mais ne peut pas être entièrement réalisée sans prise en charge de la langue, car vous avez besoin de mécanismes de langue tels que privé / statique pour vous protéger contre une utilisation accidentelle.

3) est principalement la conception du programme. Il existe généralement trois dépendances différentes: "l'objet X contient l'objet Y", "l'objet X est une sorte de Y" et "l'objet X interagit avec l'objet Y". Il existe de nombreuses fonctionnalités de langage pour aider avec ces dépendances: héritage / polymorphisme, classes de base abstraites, etc.

Maintenant, si nous regardons ce qui précède, nous pouvons voir que vous avez à peine besoin de fonctionnalités de langage pour écrire des programmes OO. Les fonctionnalités le rendent beaucoup plus facile.

Les objectifs ci-dessus ne peuvent pas être atteints en utilisant une logique en arrière boueuse: simplement parce que vous utilisez le mot-clé class, votre programme ne reçoit pas automatiquement une conception modulaire. Ce n'est pas parce que vous utilisez l'héritage que vos dépendances d'objets ont un sens. Un langage avec des fonctionnalités OO permettrait toujours des choses comme class TheWholeBloodyProgramou "Animal hérite de chat".

Malheureusement, le sujet d'une bonne conception de programme orienté objet est rarement mentionné dans ce genre de discussions. Les programmeurs endoctrinés ne regardent que la syntaxe et yap des choses comme par exemple "C ++ a des types de données primitifs donc votre programme C ++ n'est pas OO", puis ils partent pour écrire un programme carrément horrible dans leur propre langue préférée, sans utiliser la moindre allusion à conception du programme quoi que ce soit.

Pour répondre à la question: très peu de langues, voire aucune, prennent en charge la conception appropriée du programme OO. Il n'est pas pertinent de savoir quels langages possédant certaines fonctionnalités liées à l'OO tant que le programmeur ne sait pas ce que signifie la conception orientée objet. Un programmeur affirmant que certains langages sont orientés objet n'a probablement pas saisi le concept d'OO dans son ensemble. Demandez au futur programmeur OO comment il conçoit les programmes OO. Si la première chose qu'ils font est de commencer à crier des mots-clés de langue, alors vous pouvez sans risque supposer qu'ils ne connaissent pas la conception OO.

Il existe peut-être un outil de haut niveau UML sophistiqué bien au-dessus du code source brut, qui oblige le programmeur à écrire uniquement des programmes avec une bonne conception orientée objet, mais j'en doute. Les meilleurs outils de conception pour la programmation OO sont probablement encore le cerveau humain et le bon sens.


la source
Pouvez-vous préciser en quoi votre définition diffère de, par exemple la programmation modulaire avec des types de données abstraits? Je pense que vous êtes sur la bonne voie, mais je ne vois pas encore le train!
Jörg W Mittag
@ JörgWMittag Ce n'est pas nécessairement différent, les ADT traditionnels peuvent être écrits en utilisant une conception orientée objet, avec une encapsulation appropriée, des setters / getters, des façons d'hériter, etc. etc. Mais ils peuvent également être écrits sans égard à la conception OO. ->
2
@ JörgWMittag Si vous avez un langage comme C par exemple, avec un support de langage limité pour OO, alors il est difficile d'écrire ADT: s d'une manière orientée objet. L'erreur la plus courante est de laisser l'attribution de l'ADT à l'appelant, c'est-à-dire de lui donner une structure publique avec tous les internes exposés, rompant l'encapsulation. La bonne façon de le faire en C est d'utiliser des "types opaques" (types incomplets), mais peu de programmeurs C savent les utiliser.
@Lundin: Dans l'article publié par JörgWMittag en commentaire d'une autre réponse, il y a une comparaison (IMO) intéressante entre ADT et OO.
Giorgio
Je me souviens de certains livres UML (probablement) un point supplémentaire 0. L'abstraction (soulignant l'importance de la formulation abstraite essentielle pour les relations inter-objets comme le polymorphisme, l'héritage, l'agrégation, etc.).
Yauhen Yakimovich
2

Non, il n'y a pas de définition formelle ou même utile, et il n'y en aura jamais. Pour certaines personnes, la POO signifie «classe de base universelle» et «doit utiliser la sémantique de référence, mieux avec un garbage collector» - et vous pouvez même obtenir des chicanes sur la syntaxe, l'une des choses les moins pertinentes jamais inventées.

En fin de compte, vous devez d'abord répondre à la question "Qu'est-ce qu'un objet?". Les plus bornés insisteront pour hériter d'une classe de base universelle inutile et être inutilement alloués sur un garbage collector pour se qualifier. Mais je préfère une définition beaucoup plus utile. Le but de la POO est d'avoir certaines données et certaines fonctions que vous pouvez appeler sur ces données. Donc

  • Un objet contient un état et offre certaines fonctions sur cet état.

Dans ce cas, même intqualifie. Après tout, lorsque vous écrivez du code de modèle en C ++ qui peut accepter des primitives ou des objets, il devient difficile d'argumenter que les primitives sont différentes de manière substantielle. Il n'y a rien de vraiment différent à la Vector v1, v2; v1 + v2;place de int v1, v2; v1 + v2;(sauf la sémantique d'initialisation merdique, il faut l'admettre). En outre, cela permet aux lambdas et à de telles choses d'être des objets, car ils détiennent l'état - leurs captures - et offrent une fonction sur cet état, pour appeler le lambda.

Heureusement, nous pouvons également classer les pointeurs vers des fonctions libres en tant qu'objets, car ils détiennent tous deux l'état (une adresse) et une fonction sur cet état (pour l'appeler). Donc une fonction libre devrait être autorisée - même si vous deviez dire que toutes les fonctions libres sont en fait des pointeurs de fonction globale.

DeadMG
la source
2
Je ne vois pas la nécessité d'une telle distinction. Mais deuxièmement, ils ont la même identité que tout autre objet - comparaison adresse / référence. Le fait que vous ne puissiez pas distinguer deux objets avec le même état, sauf en comparant les adresses, est loin d'être nouveau et s'applique à tous les objets.
DeadMG
5
-1. Commence par une diatribe inutile et inutile, passe rapidement à une attaque ad hominem et la seule chose même factuelle à distance (la définition de la POO ) est erronée. Veuillez lire On Understanding Data Abstraction, Revisited by William R. Cook pour la différence entre un type de données abstrait et un objet.
Jörg W Mittag
1
"Je ne vois pas la nécessité d'une telle distinction.": Mais cette distinction fait partie des caractéristiques communément admises des objets. Bien sûr, vous pouvez développer votre propre notion d'un objet qui est différent de ce qui est généralement accepté. Vous êtes totalement libre de le faire.
Giorgio
2
@ Jörg Je vous prie de différer. Je ne suis pas entièrement d'accord avec ce post, mais appeler la mise en garde dans le premier paragraphe «inutile» ou «diatribe» est fallacieux. Il n'y a pas de définition universellement acceptée de la POO. C'est un fait simple et largement reconnu. Le reste du message est une définition de la POO. Certainement pas le plus utilisé, ni celui que je donnerais, mais, comme l'a dit DeadMG, en fait assez utile.
Konrad Rudolph
2
@KonradRudolph: ce paragraphe était très différent lorsque j'ai écrit mon commentaire, y compris en comparant les programmeurs qui se soucient de la syntaxe aux racistes, mentionnant même un utilisateur spécifique de ce site par son nom.
Jörg W Mittag
0

Vous pouvez y penser par exemple négatif. Java n'est pas un langage purement orienté objet car il existe également des types primitifs qui ne sont pas des objets. Ce sont des entiers, des doubles, des tableaux et ainsi de suite. Dans un langage objet pur, la sémantique des objets est disponible pour tout.

Il y a aussi la question de savoir dans quelle mesure le langage est fermé à la modification, même dans le cadre de l'objet. En Java, vous ne pouvez pas définir de nouvelles sous-classes pour certaines classes, telles que String ou Class.

Quelles langues sont pures? Le seul candidat qui me vient à l'esprit est smalltalk.

ddyer
la source
Le langage Ruby OO n'est-il pas aussi?
zxcdw
2
@zxcdw (et ddyer): c'est exactement le problème: personne n'a de définition formelle de "pure OO", donc personne ne peut donner une réponse définitive à cette question.
Joachim Sauer