• # intéressant !

    Posté par  (site web personnel) . Évalué à 7.

    Je rajouterais un truc qui m'a fait une sorte de "mind blow" quand je m'en suis rendu compte en lisant Clean Code (?).

    Une des grandes différences entre un code objet avec plein d'objets et un code fonctionnel avec un gros arbre central utilisant un type somme, c'est qu'il est facile d'ajouter un objet en POO (comme dans un code de gestion), mais difficile d'ajouter un comportement car il faut modifier toutes les classes. A l'inverse, il suffit d'ajouter une fonction pour modifier un code fonctionnel (comme une passe d'un compilateir sur un AST), alors qu'il faut revoir tout le code, si on ajoute un type d'élément à l'arbre de donnée.

    La mode des objets sans comportement dans Java avec Getter/setter ressemble furieusement à du code fonctionnel sans en avoir le nom.

    "La première sécurité est la liberté"

    • [^] # Re: intéressant !

      Posté par  (site web personnel, Mastodon) . Évalué à 2.

      La mode des objets sans comportement dans Java avec Getter/setter ressemble furieusement à du code fonctionnel sans en avoir le nom.

      En fais ça en a le nom : la « mode » est arrivée avec celle du paradigme fonctionnel dans Java 8, et a été pérennisée avec les record (Java 17 pour la première version LTS où c’est disponible).

      La connaissance libre : https://zestedesavoir.com

      • [^] # Re: intéressant !

        Posté par  . Évalué à 2.

        Plutôt avec les beans de java 1.1 et la notion de POJO (mot inventé par Martin Fowler en 2000) qui est souvent amalgamé avec les DTO.

        Bref c'est une vielle idée.

        https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

        • [^] # Re: intéressant !

          Posté par  (site web personnel, Mastodon) . Évalué à 3.

          Pour moi c’est des notions différentes, en particulier :

          • les beans doivent être modifiables (les objets fonctionnels ne le sont qu’au besoin),
          • les beans doivent être sérialisables (ça n’est pas un besoin pour les objets utilisés dans le contexte fonctionnel),
          • les beans doivent pouvoir être étendus (ça n’est pas un besoin pour les objets utilisés dans le contexte fonctionnel)
          • les beans sont censés gérer des listeners, ce qui sort du cadre de l’objet « sans comportement »
          • les POJO c’est juste un acronyme pour parler des objets qui ne dépendent pas d’un framework particulier (en particulier face aux EJB à l’époque)

          On peut se servir de « beans » dans les parties fonctionnelles de code Java, mais ça n’est pas nécessaire que les objets utilisés recouvrent toutes les parties des beans. En fait, ça fait longtemps que je n’entends plus grand-monde parler de « beans » ou « JavaBeans » hors du contexte de code historique. Éventuellement pour parler d’un objet qui sert uniquement de « structure de données » (c’est ce dont il s’agit ici), mais j’entends plutôt parler de POJO, « data object » (par mimétisme avec les data class de Kotlin) ou de Record dans ce cas précis.

          La connaissance libre : https://zestedesavoir.com

          • [^] # Re: intéressant !

            Posté par  . Évalué à 2.

            Tu viens de répondre bien plus précisément à la remarque :

            La mode des objets sans comportement dans Java avec Getter/setter ressemble furieusement à du code fonctionnel sans en avoir le nom.

            C'est une mode très vielle (30 ans), mais ça ne fait qu'une petite dizaine d'années que c'est véritablement fait pour la programmation fonctionnelle pour tout un tas de critères qui peuvent paraître être des détails, mais qui font beaucoup au final.

            https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

  • # Oh vous savez, moi, l'objet...

    Posté par  (Mastodon) . Évalué à 6. Dernière modification le 22 juin 2023 à 08:53.

    Étant un développeur embarqué depuis la fin du siècle précédant, j'ai quasi jamais travaillé en POO.

    Sachant tout de même qu'on parle d'un des plus gros paradigmes de la programmation, j'ai voulu m'y mettre ne serait-ce que par la culture, et à chaque fois je tombe sur des explications de comment résoudre des problèmes que je n'ai jamais rencontré.

    Quand on regarde la définition de haut niveau des objets : Ces objets ont un état interne et un comportement, qui leur permet d’interagir entre eux on voit très bien que c'est ce qu'on fait depuis toujours avec un langage fonctionnel (C pour ma part), en ayant une architecture/conception rigoureuse (et pas un plat de spaghetti).

    Alors certes un langage Objet facilitera ce travail, mais en théorie seulement quand je vois le nombre d'articles (et de bouquins) destinés à bien architecturer/concevoir les objets.

    Ce billet me conforte un peu dans ma vision…

    En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

    • [^] # Re: Oh vous savez, moi, l'objet...

      Posté par  (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 22 juin 2023 à 10:06.

      Déjà un point qui m’étonne :

      on voit très bien que c'est ce qu'on fait depuis toujours avec un langage fonctionnel (C pour ma part)

      Tu parles bien de « fonctionnel » comme dans programmation fonctionnelle au sens de cette définition ? Si oui, je ne savais pas qu’on pouvait faire ça avec C.

      Quant au reste, c’est une question de facilité d’usage et de quantité d’effort à mettre sur la conception. Si ton langage est conçu pour faire de la POO (tu peux remplacer ce terme par n’importe quel autre paradigme de programmation dans la suite de la phrase), tu auras nativement les outils pour suivre ce paradigme et ça te demandera beaucoup moins d’efforts pour avoir un code correctement architecturé (selon ces paradigmes) ; l’énergie économisée peut servir à autre chose.

      D’autre part, le message principal du billet – et je crois que c’est dit explicitement dans la dernière partie – c’est surtout qu’il ne faut pas rester collé à un paradigme de programmation en particulier, et adopter ceux qui sont pertinents pour l’ensemble (problème, langage, équipe). Et donc qu’essayer de tout faire avec de la POO, c’est aussi stupide que de vouloir tout faire avec de la programmation fonctionnelle1, des ECS ou que sais-je. De la même façon, refuser l’un de ces paradigme par principe serait idiot parce que ça priverait d’un outil qui peut être utile.

      Cette volonté de coller à tout prix à un paradigme maladapté est sans doute l’un des plus gros problèmes de la POO (et là aussi je pense qu’on peut remplacer « POO » par n’importe quel autre paradigme). Le confort qu’offre le choix du paradigme est tel que beaucoup de langages modernes (ou versions modernes de langages plus anciens) fournissent nativement les outils et structures pour utiliser des techniques de programmation variées.

      Cela dit, c’est tout à fait possible que, dans les ensembles (problème, langage, équipe) que tu as rencontré dans ta vie, la POO n’était jamais la solution préférable, surtout en embarqué.


      1. Une position pourtant tenue par certains zélotes de la programmation fonctionnelle et de la théorie des langages très bruyants sur un certain pan du web informatique francophone il y a une dizaine d’années, et qui a réussi à me dégouter de ce paradigme, avant que je ne comprenne qu’il était très pratique, mais pour certains types de problèmes seulement. Ne faites pas comme ces gens, soyez ouverts d’esprit. 

      La connaissance libre : https://zestedesavoir.com

      • [^] # Re: Oh vous savez, moi, l'objet...

        Posté par  (Mastodon) . Évalué à 4.

        Tu parles bien de « fonctionnel » comme dans programmation fonctionnelle au sens de cette définition ?

        Pas du tout ! je voulais parler de langage "non objet". Tu vois donc mon niveau en théorie de la programmation…

        D’autre part, le message principal du billet – et je crois que c’est dit explicitement dans la dernière partie – c’est surtout qu’il ne faut pas rester collé à un paradigme de programmation en particulier

        Je l'entendais bien ainsi, et le choix du langage est donc primordial car il va tôt ou tard te forcer dans son propre paradigme.

        En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

        • [^] # Re: Oh vous savez, moi, l'objet...

          Posté par  (site web personnel, Mastodon) . Évalué à 3. Dernière modification le 25 juin 2023 à 08:32.

          Tu parles bien de « fonctionnel » comme dans programmation fonctionnelle au sens de cette définition ?

          Pas du tout ! je voulais parler de langage "non objet". Tu vois donc mon niveau en théorie de la programmation…

          Euh, on ne serait pas en train de causer de langage procédural, là ?

      • [^] # Re: Oh vous savez, moi, l'objet...

        Posté par  (site web personnel) . Évalué à 3.

        Tu parles bien de « fonctionnel » comme dans programmation fonctionnelle au sens de cette définition ? Si oui, je ne savais pas qu’on pouvait faire ça avec C.

        Je te rassure, le C ne permet pas ça.
        Je pense que c'est au sens langage qui fonctionne bien. Ce qui peut se discuter sur certains points.

        • [^] # Re: Oh vous savez, moi, l'objet...

          Posté par  (site web personnel, Mastodon) . Évalué à 2.

          OK, merci à vous deux. Mes cours de C sont anciens (C pour microcontrôleur en plus), mais je pensais bien que le langage n’avait pas évolué à ce point et autant au-delà de son concept de base, d’où mon étonnement !

          Quant à qualifier C de « langage qui fonctionne bien », eh bien… On va dire que ça dépend ce qu’on lui demande, et qu’on l’a très probablement beaucoup trop utilisé au-delà de ses capacités (coucou les CVE de sécurité pour des détails stupides de dépassement de pile et autres joyeusetés). Mais pour faire des trucs louches avec des microcontrôleurs exotiques, ça fonctionnait bien.

          La connaissance libre : https://zestedesavoir.com

    • [^] # Re: Oh vous savez, moi, l'objet...

      Posté par  . Évalué à 2.

      Quand on regarde la définition de haut niveau des objets : Ces objets ont un état interne et un comportement, qui leur permet d’interagir entre eux on voit très bien que c'est ce qu'on fait depuis toujours avec un langage fonctionnel (C pour ma part), en ayant une architecture/conception rigoureuse (et pas un plat de spaghetti).

      Il me semble que tu ne peux pas garantir que l'état d'un objet (une structure j'imagine ?) soit cohérent. Si par exemple tu veut un objet qui représente une intervalle représenté par la valeur basse et la valeur haute (ouvert ou fermé ne change pas mon explication), tu aimerais pouvoir garantir que la borne basse est effectivement toujours plus petite que la borne haute. Ce genre d'invariant est garanti par l'immutabilité dans les langages fonctionnels et en objet par l'encapsulation (et tu vérifie à chaque modification que l'objet continue de respecter l'invariant). En C je ne vois pas comment tu fait. Ça n'est pas un sujet théorique.

      Je peux complètement passer à côté de quelque chose au sujet de comment tu fais et tu pourra me rétorqué avec raison que des langages comme python cassent ce principe ce qui est vrai.

      Alors certes un langage Objet facilitera ce travail, mais en théorie seulement quand je vois le nombre d'articles (et de bouquins) destinés à bien architecturer/concevoir les objets.

      Ce n'est pas parce qu'il n'y a pas de silver bullet que tout est identique. Tout langage turing complet sera en mesure de produire une usine à gaz, est-ce que pour autant le shell, le C et l'haskell sont identique ?

      https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

      • [^] # Re: Oh vous savez, moi, l'objet...

        Posté par  (site web personnel) . Évalué à 4.

        en objet par l'encapsulation (et tu vérifie à chaque modification que l'objet continue de respecter l'invariant). En C je ne vois pas comment tu fait. Ça n'est pas un sujet théorique.

        Tu peux faire de l'objet en C même si c'est moins pratique et naturel qu'en C++ ou autre langage destiné à ce paradigme. D'ailleurs U-boot, GTK, GLib ou le noyau Linux le font.

        • [^] # Re: Oh vous savez, moi, l'objet...

          Posté par  . Évalué à 2.

          Je suis curieux de savoir s'il y a un moyen d'assurer l'encapsulation.

          https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

          • [^] # Re: Oh vous savez, moi, l'objet...

            Posté par  (Mastodon) . Évalué à 3.

            Le moyen le plus simple est de faire un .c à part, qui déclare la structure (allocation de mémoire) puis qui implémente l'accesseur. Il publie un .h à destination du reste du code dans lequel n'apparaît que l'accesseur.

            Techniquement, le reste du code devra passer par l'accesseur.

            En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

          • [^] # Re: Oh vous savez, moi, l'objet...

            Posté par  (site web personnel) . Évalué à 7.

            Oui, il y a des moyens.

            Typiquement la structure "FILE *" qui est utilisé dans la bibliothèque standard de C en est un exemple. Tu ne connais pas sa structure exacte de l'extérieur, tu ne le manipules jamais directement mais uniquement via des fonctions dédiées qui font la tambouille que tu veux.

            Tu peux reproduire ce concept pour n'importe quelle structure de données. Après en C si tu as vraiment envie tu as toujours moyen de contourner ces limitations, mais là on tombe plus dans le programmeur qui veut faire n'importe quoi de manière pathologique qu'autre chose.

            Après le C a ses propres faiblesses et n'est pas un langage parfait, loin s'en faut. Et il y a des langages mieux adaptées pour faire de la POO bien que le C permette de le faire raisonnablement bien.

            • [^] # Re: Oh vous savez, moi, l'objet...

              Posté par  . Évalué à 0.

              Après en C si tu as vraiment envie tu as toujours moyen de contourner ces limitations, mais là on tombe plus dans le programmeur qui veut faire n'importe quoi de manière pathologique qu'autre chose.

              Oui enfin ça s'appelle un buffer overflow si je ne m'abuse, ça fait beaucoup de porteurs dans les locuteurs, non ?

              https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

              • [^] # Re: Oh vous savez, moi, l'objet...

                Posté par  (site web personnel) . Évalué à 5.

                Je ne comprends pas ce que tu veux dire.

                • [^] # Re: Oh vous savez, moi, l'objet...

                  Posté par  . Évalué à 0.

                  Écrire dans un mauvais endroit de la mémoire ça arrive facilement. Affirmer que ça n'arrive que parce que le développeur est un malade me semble être une façon de se cacher le problème. Soit c'est qu'il y a beaucoup de malade qui écrivent du C soit c'est un vrai sujet (j'ai regardé on est à plus de 300 CVE qui concernent des buffer overflow en 2023).

                  https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

                  • [^] # Re: Oh vous savez, moi, l'objet...

                    Posté par  (site web personnel) . Évalué à 4.

                    Tu n'as pas compris mon propos.

                    Malgré le fait que par exemple l'implémentation de la structure "FILE" ne soit pas connue de l'utilisateur sans lire le code de la libc, ce qui impose d'utiliser les fonctions standards pour la manipuler ce qui est donc une encapsulation, tu peux contourner ce problème si tu as réellement envie en tapant directement dedans pour peu que tu saches comment c'est implémentée. Mais pour moi faire ça c'est un cas pathologique, tu peux le faire (mais pareil en C++ et probablement d'autres langages hein) mais ce n'est pas très intéressant de s'en soucier spécialement car personne ne fera ça réellement.

                    Là tu me parles de jardiner dans la mémoire pour exploiter des failles de sécurité ou pour contourner le programme. Cela n'a pas grand chose à voir selon moi. Par exemple le C++ qui implémente tout ce qu'il faut pour la POO et dont le fait de rendre des attributs internes non accessibles de l'extérieur souffre du même problème. Mais surtout ce n'est pas lié à une encapsulation forte ou pas. L'encapsulation c'est de ne pas exposer à un code appelant ses détails internes pour éviter un couplage fort dans le code, pas empêcher aux attaquants malveillant d'y accéder quand même avec tous les outils qu'ils ont à disposition.

                    • [^] # Re: Oh vous savez, moi, l'objet...

                      Posté par  . Évalué à 1.

                      Là tu me parles de jardiner dans la mémoire pour exploiter des failles de sécurité ou pour contourner le programme. Cela n'a pas grand chose à voir selon moi.

                      Les cas qui deviennent des problèmes de sécurité ne sont qu'une partie de ce que produit ce genre d'écriture. L'apprentissage du C passe nécessairement par l'explication de comment tu t'es créé des bugs en écrivant à côté de là où tu le souhaitais.

                      L'encapsulation c'est de ne pas exposer à un code appelant ses détails internes pour éviter un couplage fort dans le code, pas empêcher aux attaquants malveillant d'y accéder quand même avec tous les outils qu'ils ont à disposition.

                      Pas que, je le décrivais plus haut c'est garantir un invariant. Cette garantie n'est pas forcément binaire et tu parle de C++, mais python est un langage objet qui n'a que faire de l'encapsulation.

                      Après ça n'intéresse pas tout le monde et c'est assez logique que des développeurs qui apprécient leur langage qui ne le fait pas n'y trouvent pas un grand intérêt, mais c'est l'un des trucs que cherche à apporter la programmation orienté objet.

                      https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

                      • [^] # Re: Oh vous savez, moi, l'objet...

                        Posté par  (site web personnel) . Évalué à 5.

                        Les cas qui deviennent des problèmes de sécurité ne sont qu'une partie de ce que produit ce genre d'écriture.

                        Cela n'a rien à voir avec la notion d'encapsulation.

                        L'apprentissage du C passe nécessairement par l'explication de comment tu t'es créé des bugs en écrivant à côté de là où tu le souhaitais.

                        Bien sûr, mais cela n'est toujours pas de l'encapsulation. Sinon quelqu'un qui attaque un binaire en mémoire pourtant rédigé en Rust pourrait aussi modifier tes invariants à sa guise, cela n'empêche pas que le code a été rédigé de sorte que les invariants sont préservés. Ou pire, un flip bit en mémoire à cause d'un rayonnement cosmique. Tu n'auras jamais une garantie à 100% car tout peut survenir, quelque soit le langage et le système qui tourne.

                        L'important est de voir si les mesures sont en place pour apporter des garanties satisfaisantes, c'est-à-dire réduire le couplage au maximum, cacher les détails internes, manipuler certaines données en passant par des points d'accès délimités, identifiés et contrôlés. Et cela est faisable (et fait par ailleurs) en C.

            • [^] # Re: Oh vous savez, moi, l'objet...

              Posté par  . Évalué à 3.

              Après le C a ses propres faiblesses et n'est pas un langage parfait, loin s'en faut. Et il y a des langages mieux adaptées pour faire de la POO bien que le C permette de le faire raisonnablement bien.

              Je réagis juste à l'assertion « la POO c'est bof, tu code bien en C c'est pareil ». Je pense que la POO a ses propres avantages (comme la programmation fonctionnel, impérative, logique, etc) et que c'est passer à côté de ce que tente d'apporter la POO que de cacher dans un « bien coder ». D'autant que bien coder en fonctionnel ou en POO peut être inversé, c'est pas simplement du bon sens. Quand tu utilise un modèle, comprendre ce qu'il tente d'apporter (et pourquoi) pour en voir les limites là où tu l'utilise ça me parait utile.

              https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

      • [^] # Re: Oh vous savez, moi, l'objet...

        Posté par  (Mastodon) . Évalué à 5. Dernière modification le 22 juin 2023 à 11:06.

        (et tu vérifie à chaque modification que l'objet continue de respecter l'invariant)

        C'est ce dont je parlais en parlant de bonne architecture/conception : vu que tu as ce besoin, tu vas donc décider que au lieu de jouer directement dans ta structure C (chose bien évidemment autorisée par ton langage, mais c'est pas parce que c'est autorisé que tu dois le faire), tu te fais une petite fonction toute mignonne qui vérifie tes assertions avant d'effectuer la modification.

        C'est facilement testable en T.U. et du coup oui, tu es maintenant "garanti".

        C'est ce qu'on fait en avionique par exemple (où le C est très largement utilisé, y compris dans des systèmes critiques) et ça se passe très bien.

        En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

        • [^] # Re: Oh vous savez, moi, l'objet...

          Posté par  . Évalué à 2.

          C'est ce qu'on fait en avionique par exemple

          Alors en avionique[1] ils testent avec une couverture complète MC/DC, ça ne permet pas de garantir que tu ne fais pas de modification directe, mais ça assure que ce n'est pas grave si tu le fait. Avoir ça dans le langage permet de s'assurer de cette propriété bien plus facilement.

          De la même façon que tu peut écrire un code multithread correct dans n'importe quel langage, mais que rust permet de s'assurer plus facilement que tu ne fais pas trop n'importe quoi.

          https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

          • [^] # Re: Oh vous savez, moi, l'objet...

            Posté par  (Mastodon) . Évalué à 5.

            Alors en avionique[1] ils testent avec une couverture complète MC/DC

            Au passage : MC/DC c'est seulement pour le niveau A de la DO178B (j'en ai fait 12 ans, c'est sur mes souvenirs). Pour niveau B et C la couverture complète suffit.

            Ça ne permet pas de garantir que tu ne fais pas de modification directe

            Évidemment. Mais j'ai la faiblesse de partir du principe que les règles de codage sont respectées. Et encore une fois, si tu as un code bien architecturé c'est facile à montrer en analyse statique du code (le seul accès à ta structure est effectivement via la fonction d'accès).

            Avoir ça dans le langage permet de s'assurer de cette propriété bien plus facilement.

            "Bien plus facilement" je suis d'accord, mais ce n'est en rien nécessaire. Comme pour revenir au sujet du journal de la POO, si tu veux bien ranger ta chambre en mettant une boîte noire avec son comportement interne d'un côté, et des interfaces de l'autre, tu n'as pas besoin d'un langage orienté objet, tu as juste besoin de faire les choses proprement (et c'est pas dur, faut arrêter aussi de se voiler la face).

            Encore une fois, les bouquins sur l'art de bien programmer en xxx ou avec le paradigme yyy sont aussi épais que ceux pour le C, donc je reste dubitatif sur le fait que ça facilite au final le boulot global d'écriture.

            Les tentations d'écrire de la merde sont universelles :)

            En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

            • [^] # Re: Oh vous savez, moi, l'objet...

              Posté par  . Évalué à 3.

              Au passage : MC/DC c'est seulement pour le niveau A de la DO178B (j'en ai fait 12 ans, c'est sur mes souvenirs). Pour niveau B et C la couverture complète suffit.

              Le niveau B demande une couverture de décision ce qui est déjà au delà d'énormément de projets.
              Le niveau C ne demande "que" une couverture de 100% des lignes.
              À noter que les niveaux inférieurs sont fait pour de très faibles criticités (je le dis pour ceux qui lisent pas particulièrement pour toi).

              À noter que même ça ne fait pas tout, Boeing a sorti de la qualité logiciel vraiment pas terrible (que ce soit pour le 737 max ou en aérospacial où la NASA a fini par faire leur propre audit de tout ce qu'a sorti Boeing).

              Mais j'ai la faiblesse de partir du principe que les règles de codage sont respectées.

              Oui enfin il existe des règles de codage pour empêcher les buffer overflow et il ne se passe pas plus de quelques jours sans qu'une nouvelle CVE en parle.

              Et encore une fois, si tu as un code bien architecturé c'est facile à montrer en analyse statique du code (le seul accès à ta structure est effectivement via la fonction d'accès).

              Il faut écrire une nouvelle règle pour chaque structure. C'est pas lourdingue ?

              Encore une fois, les bouquins sur l'art de bien programmer en xxx ou avec le paradigme yyy sont aussi épais que ceux pour le C, donc je reste dubitatif sur le fait que ça facilite au final le boulot global d'écriture.

              Pas sûr que cette métrique ai du sens.

              https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

              • [^] # Re: Oh vous savez, moi, l'objet...

                Posté par  (Mastodon) . Évalué à 4.

                Il faut écrire une nouvelle règle pour chaque structure. C'est pas lourdingue ?

                Non. Pas plus lourdingue que de certifier un compilateur qui va te le faire "automagiquement" (même si cet effort n'est à faire qu'une fois il est vrai).

                Après je parle de l'embarqué (depuis le début), traditionnellement c'est pas un monde où on trafique des dizaines de structures.

                En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

            • [^] # Re: Oh vous savez, moi, l'objet...

              Posté par  . Évalué à 4.

              Comme pour revenir au sujet du journal de la POO, si tu veux bien ranger ta chambre en mettant une boîte noire avec son comportement interne d'un côté, et des interfaces de l'autre, tu n'as pas besoin d'un langage orienté objet, tu as juste besoin de faire les choses proprement

              À partir du moment où tu as des boîtes noires tu manipules des objets. La POO n'est qu'un formalisme de cette architecture.

              • [^] # Re: Oh vous savez, moi, l'objet...

                Posté par  . Évalué à 5.

                À partir du moment où tu as des boîtes noires tu manipules des objets. La POO n'est qu'un formalisme de cette architecture.

                Non, ce sont les types de donnés abstraits qui formalisent les boîtes noires. La POO, c'est faire de l'encapsulation avec un enregistrement (record ou struct) de clôtures mutuellement récursives (les méthodes peuvent s'appeler les unes les autres) qui partagent le même environnement (les données d'instance). C'est un cas extrêmement particulier des types de données abstraits, que je n'utilise quasiment jamais parce qu'il ne sépare par les données de leurs méthodes (ce qui est pour moi presque toujours un non sens).

                Dans l'exemple à la fin de ce chapitre sur les modules de première classes de Real World Ocaml, ils font de la POO en utilisant les types de données abstraits, bien qu'OCaml soit multi-paradigme et possède un système « objet ». Ce type de données :

                module type Query_handler_instance = sig
                  module Query_handler : Query_handler
                  val this : Query_handler.t
                end;;

                est équivalent (j'ai envie de dire isomorphe) au type d'un objet au sens de la POO. Mais ici le type de this, à savoir Query_handler.t, est abstrait, c'est-à-dire que les détails d'implémentation son inconnu de l'utilisateur de l'instance. On appelle aussi ce genre de type, type existentiel, parce que la seule chose que l'on puisse dire c'est qu'il existe un certain type t qui est celui de this, mais on ne sait rien sur lui, si ce n'est qu'il possède un ensemble de méthode données par le module Query_handler. Comme on peut le voir, un objet consiste à empaqueter une valeur d'un certain type, avec un ensemble de méthodes le concernant. Mais, il n'est absolument pas nécessaire d'empaqueter ensemble données et méthodes pour faire usage de types de données abstraits. Le type du module Query_handler peut être vue comme un header .h du C qui définit un type sans en exposer les détails d'implémentation. Sa définition est :

                module type Query_handler = sig
                
                  (** Configuration for a query handler *)
                  type config
                
                  val sexp_of_config : config -> Sexp.t
                  val config_of_sexp : Sexp.t -> config
                
                  (** The name of the query-handling service *)
                  val name : string
                
                  (** The state of the query handler *)
                  type t
                
                  (** Creates a new query handler from a config *)
                  val create : config -> t
                
                  (** Evaluate a given query, where both input and output are
                      s-expressions *)
                  val eval : t -> Sexp.t -> Sexp.t Or_error.t
                end

                La seule utilité que je vois aux objets, c'est de pouvoir injecter dans un même type (celui de l'objet) des types de données autrement incompatibles (distincts) pour pouvoir les mettre ensemble dans un conteneur homogène (liste, tableaux …). C'est là seule chose à laquelle ils me servent. Sinon, pour tout ce qui est encapsulation et maintient d'invariant, j'utilise les type de données abtraits sans mélanger données et méthodes dans une même structure.

                Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

                • [^] # Re: Oh vous savez, moi, l'objet...

                  Posté par  . Évalué à 2.

                  La seule utilité que je vois aux objets, c'est de pouvoir injecter dans un même type (celui de l'objet) des types de données autrement incompatibles (distincts) pour pouvoir les mettre ensemble dans un conteneur homogène (liste, tableaux …).

                  Tu utilise pas un type somme pour ça ?

                  https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

                  • [^] # Re: Oh vous savez, moi, l'objet...

                    Posté par  . Évalué à 4. Dernière modification le 22 juin 2023 à 23:07.

                    Tu utilise pas un type somme pour ça ?

                    En fait, ce type est équivalent à un type somme, ou plus exactement la limite d'une somme infinie (comme une série convergente, en gros). Pour l'écrire ainsi, il faut utiliser les types de données algébriques généralisés ou GADT. Lors de la première édition de l'ouvrage, il n'y a avait pas encore de GADT dans le langage, d'où l'usage de modules et de types abstraits. Mais on peut aussi définir le type existentiel de l'objet ainsi :

                    (** le type des méthodes pour un type 'a donné *)
                    type 'a meth = (module Query_handler with type t = 'a)
                    
                    (** le type de l'objet avec un GADT *)
                    type t = Handler : {meth : 'a meth; this : 'a} -> t

                    C'est une somme infinie indexée par les modules de méthodes. Si on pouvait utiliser une syntaxe à la Curry pour le constructeur de GADT (c'est ce qui se fait en Haskell en mixant type classes et GADT), cela donnerait :

                    type t = Handler : 'a meth -> ('a -> t)

                    autrement dit, c'est un type somme avec une infinité de constructeur, indexés par les modules des méthodes : chaque module de type 'a meth définit un constructeur qui injecte le type 'a dans la somme t. :-)

                    Sur le forum OCaml, j'avais fait une synthèse de différentes implémentations du paradigme de la POO (avec comparaison des différentes implémentation) pour une personne qui voulait l'émuler mais ne pouvait pas utiliser la couche objet du langage. Le cas d'étude étant des données dont le comportement commun était de pouvoir être affichées et mises à jour (de manière immuable). En gros, elles devaient satisfaire cette interface :

                    module type S = sig
                      type t
                    
                      (** méthode d'affichage *)
                      val print : t -> unit
                    
                      (** méthode de mise à jour *)
                      val update : t -> t
                    end

                    Les quatres première propositions de mon commentaire caractérisent la nature d'un objet, au sens de la POO, et si l'on n'a pas besoin de les exprimer dans son code alors les objets ne servent à rien.

                    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.