kantien a écrit 1131 commentaires

  • [^] # Re: Loupé

    Posté par  . En réponse au lien La récursivité sur linuxfr. Évalué à 3.

    sans le -O3 j'ai évidemment un stack overflow ;)

    Elles sont hyper agressives les optimisations de gcc ! Même sans récursion terminale, il s'en sort. Si je fais ça en OCaml, je me paye systématiquement un stackoverflow sur de grandes entrées.

    D'ailleurs, sur ta réponse précédente tu lui reprochais de faire de l'optimisation prématurée, mais il n'y avait aucune optimisation, et c'est bien là le problème : à chaque appel récursif, il empile et ne dépile qu'à la fin de la récursion, et donc il y a stackoverflow à tous les coups. ;-)

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

  • [^] # Re: Loupé

    Posté par  . En réponse au lien La récursivité sur linuxfr. Évalué à 3.

    Ce qui fait réagir, c'est de pas l'avoir dit dans le contexte d'un langage particulier.

    Moi qui n'écris pratiquement presque que du OCaml, j'aurais pu écrire ton inversion de demande de légitimité. Si on prend le vénérable taptempo en OCaml, le premier qui vient me demander de justifier ma boucle loop récursive par rapport à une immonde boucle while risque de regretter sa demande de justification. ;-)

    Les fonctions récursives c'est le pendant calculatoire des constructions par récurrence et du raisonnement par récurrence. Le plus simple d'entre eux étant le raisonnement par récurrence sur les nombres entiers (représentés de manière unaire) :

    • si une propriété est vraie de 0 ;
    • si elle est vraie de n alors elle est vraie de n + 1 ;
    • alors elle est vraie de tout entier.

    Il existe une autre version de l'hypothèse de récurrence qui devient :

    • si elle est vraie de tout entier ≤ n alors est vraie de n + 1

    Dans la première formulation la taille de l'hypothèse est constante (le cas n), dans la seconde elle croît linéairement avec n (la conjonction de tous les cas jusqu'à n).

    Dans le premier cas, on a une récursion terminale qui utilise un espace constant sur la pile; dans le second l'espace consommé croît linéairement avec la taille de l'entrée, on risque le débordement de pile.

    Les entiers unaires n'étant rien d'autres que des listes chaînées, le module des listes de la bibliothèque standard de OCaml contient une grande quantité de fonctions récursives (dont certaines ne sont pas terminales récursives).

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

  • [^] # Re: Bullshit Bingo !

    Posté par  . En réponse au lien Le design des programmes - Des façons de faire du numérique. Évalué à 3.

    Je serai curieux de recueillir ton ressenti sur la partie concernant la machine de Turing mais il me semble que c'est du même acabit.

    Oui, il y a du grand n'importe quoi. Ce matin j'avais juste relevé une formulation erronée du résultat d'incomplétude, ce qui peut encore passer, mais la suite est bien pire quand il interprète cela par le fait que « tout programme est voué à l'incomplétude : il finira par planter ». Ça n'a absolument rien à voir et ce genre d'interprétation est typique de l'école de pensée que critique Bouveresse dans sa conférence. Un bug ou un plantage, c'est plutôt le signe d'une preuve mathématique fausse ou d'une preuve d'un mauvais théorème (on prouve bien quelque chose, mais pas le théorème dont on souhaite faire usage). Mais pour voir cela, il faut passer par la correspondance de Curry-Howard, magnifiquement décrite par Jean-Louis Krivine dans sa conférence À propos de la théorie des démonstrations (du programme de Hilbert aux programmes tout court).

    Cependant, l'auteur n'est pas informaticien ni mathématicien (il me semble que le travail sur ce genre d'objets ne concerne qu'une petite part des informaticiens) mais théoricien en design.
    Cette partie semble là pour cerner le numérique depuis ces débuts et ne constitue pas le cœur du travail de l'auteur, qui se déploie dans les parties suivantes où il analyse les manifestations plus récentes et palpables de la chose numérique.

    Certes mais il utilise un style d'une école de pensée que je rejette totalement, et même s'il peut s'y trouver des choses intéressantes, c'est noyé dans un tissu d'absurdité. Le chapitre suivant sur le memex est du même ordre, où l'on y trouve du n'importe quoi philosphique quand il emploie totalement à contresens des notions issues de la morale kantienne. De plus sa vision du memex rejoint ce que dit Bouveressse :

    Il est vrai que, si on pense, comme c'est souvent le cas, que dans le domaine littéraire et philosophique, la pensée procède essentiellement sur le mode de l'association d'idées et que celle-ci est par essence créatrice et peut créer tout ce qu'on veut, sauf, bien entendu, de l'obscurité et de la confusion, il est difficile de trouver encore quelque chose à critiquer et de comprendre ce qui, dans le discours de nos intellectuels, a pu choquer des lecteurs comme Sokal et Bricmont.

    Franchement, je suis allé jusqu'au chapitre sur la genèse du Web, mais j'ai vraiment pas envie d'aller plus loin.

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

  • [^] # Re: Bullshit Bingo !

    Posté par  . En réponse au lien Le design des programmes - Des façons de faire du numérique. Évalué à 3.

    Je n'ai pas compris ta démonstration, trop technique pour moi.

    Elle fait implicitement usage d'un autre théorème de Gödel, qui a moins fait parler de lui que l'incomplétude, mais tout aussi important et que Bouveresse mentionne dans sa conférence : le théorème de complétude du calcul des prédicats, qui exprime qu'une théorie est cohérente si et seulement si elle a un modèle.

    Ainsi, si la théorie T des corps algébriquement clos n'est pas complète alors elle possède un énoncé E indécidable tel que les théories T + E et T + non E soient cohérentes. Par le théorème de complétude elles ont chacune un modèle dénombrable, qui ne peut être que la clôture algébrique du corps des rationnels (c'est le seul corps algébriquement clos et dénombrable); corps qui devraient alors satisfaire à la fois les énoncés E et non E, ce qui est contradictoire. Donc T est complète.

    C'était très amusant par ailleurs, et tout à fait accessible au profane.

    Écrire clairement dans une langue acccessible aux communs des mortels n'est pas du goût d'une certaine intelligentsia française. :-P

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

  • [^] # Re: Bullshit Bingo !

    Posté par  . En réponse au lien Le design des programmes - Des façons de faire du numérique. Évalué à 6. Dernière modification le 27 juillet 2023 à 08:56.

    Cette thèse est un travail de six ans et 550 pages (!). Je pense que la réduire à trois citations et en profiter pour tirer une généralité ouvertement provocatrice sur son contenu n'est pas très honnête, mais ce n'est que mon avis.

    Je dois avouer avoir eu la même réaction que patrick_g, mais j'ai coutinué jusqu'à l'introduction et le début de la première partie historique. Les références à Dérida et Deleuze ont allumé mes warnings (éveillant le spectre des Impostures intellectuelles et de l'affaire Sokal), après lecture de l'introduction on ne sait toujours pas de quoi va traiter cette thèse et, qui plus est, elle n'a pas de plan ni de structure, ce qui est parfaitement assumé. Puis vient la première partie avec Gödel et Turing, et là c'est le drame !

    Non Gödel n'a jamais prouvé que « tout système formel comporte au moins une thèse qui n’est pas démontrable dans ce système (à l’exception des axiomes qui sont là par principe) », il a prouvé que certains systèmes formels avaient cette propriété. Pour qu'un système formel soit essentiellement incomplet et impossible à compléter (chacune de ses extensions seront aussi incomplètes), il faut et il suffit que sa capacité d'expression permette de réfléchir en lui-même sa propre méta-théorie (c'est l'utilité de toute la première partie de la preuve de Gödel avec son codage des preuves comme énoncés arithmétiques).

    En revanche, il existe des systèmes axiomatiques incomplets ayant des extensions complètes, par exemple la théorie des corps. Ainsi, dans l'axiomatique des corps, la question « tout polynôme admet-il une racine ? » est indécidable. Néanmoins, la théorie des corps algébriquement clos est une extension de la première, récursivement énumérable et complète (elle n'admet qu'un seul modèle dénombrable, à isomorphisme près, à savoir la clotûre algébrique du corps des rationnels) !

    Tout ce que je viens de dire ne représente qu'un semestre d'étude pour un étudiant en master, ce qui est peu par rapport aux 6 ans de travaux qu'ont demandé la thèse. Il serait peut être tant que les adeptes de Dérida et Deleuze cessent toute référence à Gödel, ou qu'ils se décident enfin à le comprendre : voir la conférence de Jacques Bouveresse Qu'appellent-ils "penser" ?.

    Je dois avouer avoir arrêté ma lecture à cet endroit de la thèse, peut-être la reprendrai-je quand j'aurai du temps à tuer.

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

  • [^] # Re: pas si simple

    Posté par  . En réponse au lien FUN : L’intelligence artificielle n’existe pas, par Luc Julia. Évalué à 2. Dernière modification le 22 juillet 2023 à 21:48.

    Que vient faire Jean-Louis Krivine dans votre discussion ? J'ai énormément de respect pour cet homme, il fut mon maître et m'initia aux arcanes du lambda-calcul typé et à la correspondance de Curry-Howard (qui était le sujet central de sa recherche à la fin de sa carrière), mais je ne vois absolument pas ce qu'il vient faire dans votre discussion.

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

  • [^] # Re: Les devoirs sont 2x plus chers les jours fériés

    Posté par  . En réponse au journal [HS] combien fait 0,12 à l'infini ?. Évalué à 5. Dernière modification le 15 juillet 2023 à 14:44.

    c'est d'ailleurs la méthode standard pour obtenir l'écriture de la forme a/b à partir d'un développement décimal.

    Une précision pour ajouter que cela marche à tous les coups pour les rationnels car leur développement décimal est cyclique : il s'obtient par une série de divisions euclidiennes dont le diviseur est le dénominateur de la fraction (ici b), divisions qui n'ont qu'un nombre fini de reste possible, et donc on finit nécessairement dans un cycle. Autrement dit, si il y a un cycle, c'est un rationnel.

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

  • [^] # Re: Tirs mortels

    Posté par  . En réponse au lien Tirs mortels en France: un problème systémique (vidéo, 3min). Évalué à 2.

    Je vois dans son texte différents exemple où il remet en cause l'État. Il ne me semble pas dire que l'État ne devrais s'occuper que de certains sujets régaliens comme l'affirme le courant de pensé qu'on appel aujourd'hui les libéraux.

    Si c'est un libéral classique tant en politique qu'en économie. Voir son texte L'État :

    Quant à nous, nous pensons que l’État, ce n’est ou ce ne devrait être autre chose que la force commune instituée, non pour être entre tous les citoyens un instrument d’oppression et de spoliation réciproque, mais, au contraire, pour garantir à chacun le sien, et faire régner la justice et la sécurité.

    Autrement dit l'État doit se résumer à ses fonctions régaliennes.

    C'est pour cela que j'avais mis son intervention à l'Assemblée, non pour dire qui il était, mais pour illustrer qu'un libertarien acclamé par des socialistes eut été cocasse. ;-)

    Pour le reste tu interprètes de travers son introduction : elle ne contient aucune argumentation, ce n'est pas leur place, et sa référence à Dieu n'a aucune valeur argumentative au sein de l'ouvrage (tel Laplace, il aurait pu s'en dispenser).

    Il considère tout cela comme parfaitement objectif. Il considère qu'il y a une unique solution, qu'elle est atteignable, qu'elle est universelle,… Alors que tout cela est culturel.

    Oui, tout comme moi, il est rationaliste et donc jusnaturaliste. Le relativisme culturel et le positivisme juridique est antinomique avec le courant rationaliste de pensée.

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

  • [^] # Re: Tirs mortels

    Posté par  . En réponse au lien Tirs mortels en France: un problème systémique (vidéo, 3min). Évalué à 2.

    J'avais oublié ce point :

    Il n'a pas d'état stable qui serait parfait ou pas. L'objectif d'une politique n'est pas l'utopie mais d'influencer ce système vers une direction ou une autre.

    Je ne suis pas utopiste et Bastiat ne visait pas non plus l'utopie. En revanche, pour nous le but d'une politique n'est pas d'influencer le système mais d'être juste et de laisser les acteurs du système, c'est-à-dire la société civile, aller où bon leur semble dans les limites de la justice. Pour citer Benjamin Constant :

    Que l'autorité se borne à être juste, nous nous chargerons d'être heureux.

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

  • [^] # Re: Tirs mortels

    Posté par  . En réponse au lien Tirs mortels en France: un problème systémique (vidéo, 3min). Évalué à 2.

    Je ne sais pas trop quoi répondre, ni comment tu as pu arriver à de telles conclusions. Ôte moi d'un doute : tu as lu tout le traité ou juste la page du lien, qui n'en est que l'introduction ? J'aurais peut être du donner le lien de la tables des matières.

    En tout cas, les socialistes de son temps étaient plus ouverts d'esprit, lorsqu'ils l'acclamèrent à la tribune de l'Assemblé Nationale, tandis qu'il défendait un amendement pour légaliser la création de syndicats et le droit de grève. Outre le fait que ce fût un grand économiste (mon premier lien est un traité d'économie bien plus rigoureux, en la matière, que le Capital de Karl Marx), il fût député et membre de la commission des finances durant l'éphémère seconde République. Malheureusement, l'amendement qu'il défendit ne fût pas voté, et il fallut attendre la troisième République.

    J'ai du mal avec cette tendance contemporaine consistant à importer du vocabulaire américain, là où nous possédons déjà le vocabulaire adéquate. Ce n'était pas un libertarien mais un libéral tout ce qu'il y a de plus classique, aussi bien en politique qu'en économie. Ensuite où vois-tu toute cette série de sophismes dont tu l'accuses. Il se réclame de la science car son livre est un traité de sciences économiques, et il ne considère pas par principe tout ce qui ne va pas dans son sens comme une erreur, mais il le prouve dans la suite de son traité. Encore faut-il l'avoir lu !

    Si l'on prend le concept de lutte des classes chez Marx, par exemple. La structure logique de son argumentaire (oui j'ai lu le Capital, quand je critique un traité, je l'ai lu) est schématiquement la suivante :

    • la valeur d'un bien (ou service) provient seule du travail, et la quantité de travail détermine la valeur (théorie de la valeur travail qu'il emprunte à David Ricardo, pourtant théoricien de l'école libérale anglaise);
    • seul l'ouvrier travail et met en œuvre le capital;
    • en conséquence de la théorie précédente, toute la plus-value lui revient;
    • or le capitaliste, par sa rente, prélève une part de cette plus-value;
    • donc le capitaliste vole l'ouvrier d'un bien qui lui revient de droit.

    De cette conclusion, entre autres, il développe une théorie de la lutte des classes qui serait le moteur de l'Histoire, connue sous le nom de matérialisme historique. Marx se prenait pour le Newton de l'Histoire, cette lutte des classes étant le centre de la dynamique historique à l'instar de la gravitation universelle de Newton pour la dynamique des corps célestes. Si il y en a un qui avait le melon (et à tort), c'est plutôt Marx, et ses thèses n'avaient absolument rien de scientifique ni dans sa démarche, ni dans ses hypothèses. Je t'invite à lire le Capital pour t'en convaincre. Méthode que savait pertinemment suivre Bastiat, ainsi qu'une rigueur logico-déductive à toute épreuve (lit son discours à l'assemblée pour t'en convaincre) qui faisait complètement défaut à Marx.

    Par exemple, Bastiat avait réfuté par avance (son traité est antérieur au Capital) la théorie de la valeur-travail de Ricardo dans le chapitre 5 du traité, chapitre dédié à l'étude de la notion de valeur marchande. Comme pour réfuter un syllogisme il suffit de réfuter les prémisses, comme pour un bâtiment dont on a sapé les fondations et dont s'ensuit l'effondrement, il ne reste plus grand chose pour soutenir l'édifice du Capital. Pour la question de la légitimité de la rente, cela se trouve ici.

    Enfin, il n'a jamais considéré la société comme une fonction mathématique à laquelle il faut trouver une solution, mais bien comme un problème qui relève du droit et de la justice (cf. encore une fois, son discours à l'Assemblée). D'ailleurs à l'origine, en France, les facultés d'Économie étaient subordonnées aux facultés de Droit. C'est en cela que je le trouve Kantien dans l'esprit (bien qu'il ne l'ait jamais lu) : il traite la question du point de vue du Droit (lieu où, pour un kantien, faire usage de mathématique relève de l'hérésie), et totalement formaliste dans sa méthodologie (il fonctionne beaucoup par comparaison d'exemples, en ne retenant que l'élément formel qui les relie entre eux, pour en déduire ses principes) et sa doctrine se formalise parfaitement dans la doctrine du Droit de Kant. Il procède ainsi pour établir sa thèse, annoncée dans l'introduction, que les intérêts individuels sont harmoniques et non antagoniques (il n'y a pas de luttes des classes). Et si tu n'aimes pas les sophismes, je te propose sa série sur les Sophismes Économiques; où l'on voit qu'il n'use pas à tort et à travers du terme de sophisme (comme c'est devenu la mode), qu'il sait exposé les thèses sophistiques et révéler ce qu'il y a de sophistique en elle (c'est-à-dire les réfuter).

    J'aurais bien développer sur cette idée de la religion disant qu'il faut mourir pour elle (quelle drôle d'idée !), mais je me contenterai d'une citation :

    La religion (considérée subjectivement) est la connaissance de tous
    nos devoirs comme commandements divins. Celle dans laquelle je
    dois savoir au préalable que quelque chose est un commandement
    divin pour le reconnaître comme mon devoir est la religion révélée (ou
    qui nécessite une révélation) ; celle, en revanche, dans laquelle je dois
    d’abord savoir que quelque chose est un devoir avant que je puisse le
    reconnaître comme un commandement divin, est la religion naturelle.
    – Celui qui proclame que seule la religion naturelle est moralement
    nécessaire, c’est-à-dire est un devoir, on peut aussi l’appeler
    rationaliste (en matière de foi). Lorsque ce dernier nie la réalité de
    toute révélation divine surnaturelle, on l’appelle naturaliste ; mais s’il
    admet cette révélation tout en prétendant qu’il n’est pas
    nécessairement exigé pour la religion de la connaître et de la tenir
    pour réelle, on pourrait l’appeler un pur rationaliste ; alors que s’il
    tient la foi en cette révélation pour nécessaire à la religion universelle,
    on pourrait l’appeler un pur supranaturaliste en matière de foi.

    Kant, La Religion dans les limites de la simple raison.

    Pour ma part je suis un rationaliste naturaliste en la matière (même si j'ai une représentation trinitaire de la divinité, par analogie à la structure formelle trinitaire de l'esprit humain : raison, entendement et faculté de juger) et pour Bastiat, d'après mes lectures, je le vois aussi comme un rationaliste en la matière. Dans un filiation, typiquement kantienne, il n'est pas pour nous concevable que les lois de la nature et les lois morales, voulues par le Créateur Suprême, soient en contradiction; mais développer un tel point m'aménerai trop loin dans l'exposé de la philosophie kantienne.

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

  • [^] # Re: Tirs mortels

    Posté par  . En réponse au lien Tirs mortels en France: un problème systémique (vidéo, 3min). Évalué à 1. Dernière modification le 04 juillet 2023 à 23:33.

    Et j'ai beau être très marqué politiquement, la lutte des classes ne semble pas protéger de prendre sa voiture et de s’emplafonner le premier badaud malheureux.

    Quelque peut hors sujet, mais comme je sais que tu es ouvert d'esprit sur le plan intellectuel, il y a cet ouvrage qui est totalement Kantien dans l'esprit, c'est-à-dire sur la manière d'argumenter, et qui est à des kilomètres du Capital de Karl Marx. Les harmonies économiques de Frédéric Bastiat.

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

  • [^] # Re: Tirs mortels

    Posté par  . En réponse au lien Tirs mortels en France: un problème systémique (vidéo, 3min). Évalué à 3.

    moi j'en sais rien je me tiens à l'écart de la télé, la radio et les sites qui relaient la parole d'extrême droite, droite dure, droite décomplexée etc

    Petit conseil : ne reste jamais loin de tes ennemis, c'est la meilleur façon de rester correctement armé pour lutter contre eux. ;-)

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

  • [^] # Re: pendant ce temps là sur Ars

    Posté par  . En réponse au lien J’ai ma propre instance Mastodon. Sept mois plus tard, je déconseille. . Évalué à 4.

    En effet Mastodon évite la plupart des trolls, des bots et une grande partie des toxiques qu’on trouve sur les réseaux.

    On peut faire l'hypothèse que cela est du aux bugs considérés comme des features. En effet, les profils que tu décris, et pour reprendre le vocabulaire de Drew DeVault, sont plus intéressés par des rapports « parasociaux » que « sociaux ».

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

  • [^] # Re: Tirs mortels

    Posté par  . En réponse au lien Tirs mortels en France: un problème systémique (vidéo, 3min). Évalué à 5.

    Non, ce qui est visé c'est la doctrine et l'idéologie de son père et de ses soutiens, comme te l'explique El Titi dans ce commentaire; doctrine vis à vis de laquelle, ils font preuve de deux poids, deux mesures.

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

  • [^] # Re: Tirs mortels

    Posté par  . En réponse au lien Tirs mortels en France: un problème systémique (vidéo, 3min). Évalué à 2. Dernière modification le 30 juin 2023 à 22:20.

    Je trouve surtout problématique de stigmatiser ce gars à cause de son père.

    Il me semble que les cibles de la critique sont surtout son père et ses soutiens. ;-)

    la lutte des classes

    Kantisme et marxisme ne font pas bon ménage, alors le moteur de l'histoire selon le matérialisme historique, ça me passe au-dessus de la tête.

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

  • [^] # Re: Tirs mortels

    Posté par  . En réponse au lien Tirs mortels en France: un problème systémique (vidéo, 3min). Évalué à 6.

    C'est quoi « l'idéologie » de Nahel par exemple ?

    Le lien d'origine d'El Titi renvoie vers un article sur le délit dont s'est rendu coupable le fils d'Éric Zemmour. Encore un gamin élevé par des parents démissionnaires, qui ne lui ont pas appris à ne pas conduire en étant saoul. Je crois bien que c'est cette contradiction que voulait mettre en avant El titi. ;-)

    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  . En réponse au lien Un point sur la programmation objet (POO) – La POO, ses problèmes, et qu’en faire . É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.

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

    Posté par  . En réponse au lien Un point sur la programmation objet (POO) – La POO, ses problèmes, et qu’en faire . É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: Sponsors en général

    Posté par  . En réponse au journal Pour ou contre Red Bull ? tu en penses quoi, toi, journal ?. Évalué à 2.

    Un peu comme au tennis

    Euh, tu peux développer là, sur le côté routinier du tennis ? Ou alors, tu ne vois le tennis qu'au travers de Roland Garros (et même sur terre, ce n'est pas si routinier que cela, bien que ce soit une surface de merde) ?

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

  • [^] # Re: Quand je lis ça ....

    Posté par  . En réponse au lien L'homme à coque. Évalué à 4. Dernière modification le 17 juin 2023 à 21:31.

    J'ai pu le vérifier pas plus tard que dimanche dernier quand j'ai loué une voiture

    Comme tu le dis par la suite, ça dépend des personnes. J'ai pu le vérifier pas plus tard que cet après-midi, où je me suis retrouvé en première dans une côte en attendant d'avoir l'espace latéral suffisant pour doubler une file de cycliste, et cela sans m'exciter derrière mon volant (ce qui n'était pas le cas de mon passager, qui pestait). ;-)

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

  • [^] # Re: Simulation

    Posté par  . En réponse au journal Une simulation de drone de combat qui tourne mal. Évalué à 5.

    Pour vulgariser l'IA je dis que ça revient à "un programme dont on n'a pas l'algorithme".

    Ton raisonnement (qui fonctionne par contraposition), ainsi que celui de LeBouquetin, est le suivant:

    • si on a l'algorithme d'un programme, on peut anticiper son comportement dans toute situation (majeure)
    • or on ne peut pas toujours anticiper le comportement d'une IA (mineure)
    • donc on n'a pas l'algorithme d'une IA (conclusion)

    Sauf qu'il me semble que la majeure de votre raisonnement est erronée. ;-)

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

  • [^] # Re: l'héritage et les exemples pourris

    Posté par  . En réponse au lien « Clean code » : performances lamentables. Évalué à 4.

    La semaine dernière, je n'avais pas assez de temps pour développer ma pensée et revenir sur le fond de l'article du lien; aujourd'hui je le peux.

    Je voudrais d'abord revenir sur un point qu'il rejette : l'encapsulation ou les types de données abstraits, résumés sous le principe "Code should not know about the internals of objects it’s working with". C'est là un principe que je ne renierai jamais, et dont les développeurs OCaml font un usage abondant : on s'en fout, la plupart du temps, de la représentation concrète d'un type, ce que l'on veut connaître c'est son interface ou API, c'est-à-dire ce que l'on peut faire avec.

    J'ai toujours aimé la présentation qu'en faisait John C. Reynolds dans son article Types, abstraction and parametric polymorphism. Il présente l'idée sous la forme d'une fable où des étudiants d'université suivent des cours sur les nombres complexes. Certains étudiants ont pour professeur Descartes qui les définit comme une paire de nombres réels (partie réelle et partie imaginaire), tandis qu'une autre partie des étudiants a pour professeur Bessel qui les définit par leurs coordonnées polaires. Chacun définit ensuite les notions usuels sur les complexes. Puis au cours du semestre, les deux sections sont interchangées, et pourtant les étudiants ne rencontre aucune difficultés bien que les représentations concrètes choisies par chacun des enseignants soient distinctes. C'est cela l'essence des types de donnés abstraits.

    Bon revenons à nos moutons, et à l'article qui critique ce principe pour des raisons de performances. Dans un premier temps, il ne fait pas que suivre ce principe mais applique toute la panoplie de la POO. Ensuite, au lieu de faire une hiérarchie de classes, il va définir un type somme de quatre figures et faire un switch statement pour comparer les performances. Ce qui revient à implémenter quelque chose du genre :

    module Forme_simple = struct
      type t =
        | Square of float
        | Recangle of float * float
        | Triangle of float * float
        | Circle of float
    
      let area = function
        | Square width -> width *. width
        | Rectangle (length, witdth) -> length *. width
        | Triangle (base, height) -> 0.5 *. base *. height
        | Circle radius -> Float.pi *. radius *. radius
    end

    Maintenant, constatant que les formules de calculs de surfaces ont des similarité, il tente son optimisation ultime. En Ocaml cela ressemblerait à cela :

    module Forme_simple_bis = struct
      type t = {
        kind : int ;
        width : float ;
        height : float ;
      }
    
      let square w = {kind = 0; width = w; height = w}
      let rectangle width height = {kind = 1; width; height}
      let triangle width height {kind = 2; widht; height}
      let circle radius = {kind = 3; width = radius; height = radius}
    
      let coeff = [|1.0 ; 1.0; 0.5; Float.pi|]
    
      let area {kind; width; height} = coeff.(kind) *. width *. height
    end

    Il y a déjà un point problématique dans son code s'il ne cache pas la représentation de son type à l'extérieur : comment garantir l'invariant qu'un carré a nécessairement une largeur égale à sa hauteur ?

    Ensuite au niveau des interfaces, chacun des deux modules peuvent se voir donner exactement la même :

    module type Forme_simple = sig
      type t
    
      (* constructeurs de formes *)
      val square : float -> t
      val rectangle : float -> float -> t
      val triangle : flaot -> float -> t
      val circle : float -> t
    
      (* méthodes sur les formes *)
      val area : t -> float
    end

    Et maintenant, il y a même mieux entre ces deux modules : algébriquement, ces deux structures sont totalement isomorphes (comme pour Descartes et Bessel dans la fable de Reynolds). Autrement dit, elles sont complétement équivalentes pour l'utilisateur et, en tant qu'implémenteur, je peux passer de l'une à l'autre sans perturber aucunement le code client, à la condition de respecter le principe Code should not know about the internals of objects it’s working with. ;-)

    Enfin, si l'on revient à mon graphe de la catégorie des structures algébriques correspondantes, comme pour le type Top il n'y a pas qu'une implémentation possible pour la somme de quatre structures. Ce qu'il a constaté c'est qu'en choisissant une implémentation adaptée, on peut avoir un code plus performant. En revanche, si on ne veut pas perturber le code client de nos modules, il faut cacher les détails d'implémentation. D'ailleurs, si seule la méthode area l'intéresse, je peux lui proposer un choix encore plus drastique pour la représentation du type t, à savoir type t = float :-P Autrement dit, on calcule une bonne fois pour toute la surface à la construction (ce qui ne marche réellement que si les valeurs sont immuables ;-)

    Une dernière petite remarque pour la route : ces deux modules de formes simples ne sont, par contre, pas isomorphes à la structure Top de la catégorie (celle que l'on manipule en faisant de la POO). Elles n'en sont que des sous-structures, car elles ne contiennent pas toutes les formes possibles et imaginables mais seulement quatre. Ce qui signifie que toutes le formes simples sont des formes, notion qui n'a absolument rien à voir avec l'héritage et une hiérarchie de classes (mais c'est là une toute autre histoire… ;-).

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

  • [^] # Re: l'héritage et les exemples pourris

    Posté par  . En réponse au lien « Clean code » : performances lamentables. Évalué à 4.

    Je le trouve inadapté pour modéliser des concepts issus des langages fonctionnels

    Ça ne sert effectivement à rien. Un jour j'ai demandé à quelqu'un de m'expliquer l'UML, au bout de dix minutes je lui ai dit d'arrêter : je n'avais rien à apprendre d'une personne qui ne sait pas structurer logiquement sa pensée de manière adéquate. En revanche j'use abondamment de diagrammes : ceux de la théorie des catégories. Bon après, j'ai une gros rejet de la POO, non du concept d'objet de la POO, mais du paradigme dans lequel tout est objet (à la Java). C'est pour moi un paradigme d'asile d'aliéné, ou l'art de faire de l'algèbre en marchant sur la tête. Je m'explique en reprenant le cas d'étude de l'article.

    Qu'un carré, un rectangle ou un cercle soient des formes, il n'y a là aucun doute. Mais cette propriété n'a rien à foutre dans leur définition ! Ce qui est inévitablement le cas si on les définit comme des objets. Personnellement je les définit ainsi :

    module Carré = struct
      type t = {width : float}
    
      let make width = {width}
    
      let area {width} = width *. width
    end
    
    module Rectangle = struct
      type t = {
        width : float;
        length : float;
      }
    
      let make width length = {widht; length}
    
      let area {width; length} = width *. length
    end
    
    module Cercle = struct
      type t = {radius : float}
    
      let make radius = {radius}
    
      let area {radius} = Float.pi *. radius *. radius
    end

    Ce qui définit chacun des types, ce sont les enregistrements et la propriété qu'ils ont d'avoir une surface se traduit par l'existence d'une fonction area sur chacun de ces types. Après le concept d'un objet, au sens de la POO, c'est le type suprême de toutes les formes, celui dans lequel on peut injecter n'importe quel forme. Ce que ne semble pas avoir compris l'auteur de l'article du lien, puisqu'il ne considère que le type somme de quatre formes possibles, alors qu'il y a aussi n'importe quel polygone, des ellipses…

    Et voilà comment on définit, algébriquement, un tel type :

    module type Shape = sig
      module type S = sig
        type t
        val area : t -> float
      end
    
      type 'a meth = (module S with type t = 'a)
      (* les valeurs de type `t` sont des formes *)
      type t
    
      (* toute valeur d'un type `'a` qui possède une méthode `area` est une forme *)
      val make : 'a meth -> 'a -> t
    
      val area : t -> float
    end

    Je n'ai donné que l'interface (ou API) d'un module qui définit ce genre suprême, sans préciser les détails d'implémentation ("Code should not know about the internals of objects it’s working with" ;-). Pour l'implémentation du type Shape.t je peux prendre aux choix :

    • un objet : type t = < area : unit -> float >
    • une clôture : type t = unit -> float
    • un gadt : type t = Shape : {meth : 'a meth; self : 'a} -> t

    et la liste n'est pas exhaustive.

    Et c'est là qu'interviennent les diagrammes de la théorie des catégories. Une forme est caractérisée par l'existence d'une fonction area sur son type. Algébriquement cela se traduit par l'étude des structures algébriques ayant la signature Shape.S :

    module type S =
      type t
      val area : t -> float
    end

    On peut faire un graphe orienté de toutes ces structures : chaque nœud du graphe est un module satisfaisant cette signature, et chaque arête est une fonction qui transforme un nœud en un autre (par exemple, la proposition tous les carrés sont des rectangles est représentée par une telle arrête). Mais dans ce graphe (qui, en soit, contient une infinité de nœuds), il y a un nœud particulier T (ou plutôt une famille de nœud). Ce dernier à la propriété que pour tout autre nœud N du graphe il existe une et une seule arrête qui va de N à T. Ce nœud T est le type Top de toutes ces structures algébriques, celui qui les contient toutes (les carrés, les rectangles, les cercles…). En réalité, il y a une infinité de tels nœuds Top, mais ils sont tous équivalents et ne diffèrent que par leurs détails d'implémentation (j'en ai donné 3 possibles au-dessus). La fonction centrale de cette structure c'est de faire du dynamic dispacth ou du polymorphisme ad-hoc : il applique la fonction area adéquate à la forme qu'il contient. Mais la stratégie à base d'objets et de vtable n'est qu'une solution parmi d'autre pour faire cela. On trouve par exemple, dans des langages existant :

    • les modules (ou les objets) en OCaml ;
    • les objets dans tout langage orienté POO ;
    • les interface en Golang ;
    • les type class en Haskell ;
    • les template en C++ (c'est l'équivalent des modules OCaml) ;
    • les traits en Rust ;
    • et bien d'autres encore.

    Mais pour définir une fonction sur une liste de formes, ou sur une forme quelconque, c'est-à-dire pour faire du polymorphisme ad-hoc, il n'est absolument pas nécessaire de les injecter dans le type Top (qui est le type des objets de la POO), et c'est ce que je reproche à la POO : elle réduit la catégorie à son seul objet terminal (ce type Top), ce qui est une manière plus que bancal de faire de l'algèbre. D'autant que de nombreuses catégories de structures algébriques n'ont pas d'objet terminal, à commencer par toutes celles qui ont des opérateurs binaires (addition, multiplication), où il devient alors vraiment ridicule de suivre le paradigme du tout objet.

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

  • [^] # Re: Pour ceux qui ressortent encore régulièrement que ces "AI" "créent" des images…

    Posté par  . En réponse au lien "Extracting Training Data from Diffusion Models" - Stable Diffusion (et autres "AI") et copyright. Évalué à 3.

    Il y a bien cette citation que l'on attribue à Georges Bernanos (je ne sais si elle est apocryphe ou non) :

    On ne comprend absolument rien à la civilisation moderne si l'on n'admet pas tout d'abord qu'elle est une conspiration universelle contre toute espèce de vie intérieure.

    Or si l'être humain se détourne de toute vie intérieure, il ne peut combler le vide resenti que par sa vie extérieure, ce qui se traduit, inévitablement, par une augmentation sans frein de sa consommation de biens…

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

  • [^] # Re: Tuteur textile

    Posté par  . En réponse au journal Jardinage : tu as commencé tes semis ?. Évalué à 3. Dernière modification le 08 février 2023 à 21:34.

    Comme toi j'hésite, surtout que cette année je vais augmenter ma surface de culture (et donc mon besoin en tuteur). Par contre, l'an dernier je me suis retrouvé avec des cultures cramées (fleur de tomates brûlées qui ne donnent pas de fruits, framboises à moitié brûlées, jamais vu ça) alors que j'avais préparé des protections anti-pluie car il y a deux ans l'excès de pluie m'avait fait perdre une partie de ma production (fraise et tomate). Résultat, je me demande si je ne devrais pas mettre en place une charpente qui s'adapte aux conditions…

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