Quand le code rencontre Platon : métaphysique des abstractions en programmation

Chaque fois qu'un développeur écrit class Animal, il rejoue sans le savoir un geste philosophique vieux de vingt-quatre siècles. Il pose l'existence d'un universel — « l'animalité » — dont chaque instance particulière (mon_chat = Animal("Félix")) ne serait qu'une manifestation concrète. La programmation informatique, loin d'être un pur exercice technique, constitue l'un des laboratoires métaphysiques les plus féconds de notre époque. Les entités qu'elle manipule — classes, objets, types, interfaces, fonctions — soulèvent des questions ontologiques que les philosophes débattent depuis l'Antiquité. Que sont ces abstractions ? Existent-elles indépendamment de nous, comme les Formes platoniciennes ? Ne sont-elles que des noms commodes, comme le soutenaient les nominalistes médiévaux ? Ou bien la programmation invente-t-elle une catégorie d'être entièrement nouvelle ?

La querelle des universaux se joue désormais en Java

Le problème des universaux — cette question de savoir si les propriétés générales (la « rougeur », l'« humanité ») existent réellement ou ne sont que des mots — est peut-être la plus longue controverse de l'histoire de la philosophie occidentale. Or la programmation orientée objet en propose une mise en scène d'une clarté saisissante.

Considérons une hiérarchie de classes Java : Animal → Mammifère → Chien. Cette arborescence reproduit presque trait pour trait l'Arbre de Porphyre, l'outil logique néoplatonicien qui organisait les êtres du genre le plus général (la Substance) jusqu'aux individus particuliers. Comme l'a montré le philosophe Wojciech Tylman dans une étude publiée en 2018, les similitudes entre la théorie platonicienne des Formes et la programmation orientée objet sont frappantes: une classe définit des propriétés sans valeurs spécifiques, des méthodes sans implémentation — elle est le modèle idéal d'un type d'entité. L'objet instancié, lui, reçoit des valeurs concrètes et entre dans le monde de l'exécution, exactement comme un particulier « participe » à sa Forme chez Platon.

Mais cette analogie platonicienne a ses limites. Aristote refusait que les Formes existent dans un royaume séparé : pour lui, l'universel n'existe que dans les particuliers. Si tous les chiens disparaissaient, la « chiennité » s'évanouirait avec eux. Or c'est précisément la philosophie qu'adoptent les langages à prototypes comme JavaScript, où il n'existe pas de classes à proprement parler : chaque objet est cloné à partir d'un autre objet particulier. Pas d'essences transcendantes, pas de royaume des Formes — seulement des individus qui se ressemblent. Le choix entre un langage à classes et un langage à prototypes est, en un sens, un choix métaphysique.

L'interface, ou la Forme pure faite code

Si les classes évoquent les universaux, les interfaces en sont la version la plus radicale. En Java ou en Go, une interface — disons Dessinable avec sa méthode dessiner() — définit un contrat pur : elle spécifie ce que quelque chose doit pouvoir faire sans jamais dire comment. On ne peut pas l'instancier directement. Elle n'a ni état, ni implémentation, ni existence matérielle propre. Elle est spécification sans substance, forme sans matière.

C'est exactement la définition d'une Forme platonicienne. La Justice chez Platon n'est aucun acte juste particulier, mais le modèle que tout acte juste doit honorer. De même, l'interface Comparable n'est aucun algorithme de tri — elle est la condition de possibilité de tout tri. Le célèbre précepte du Gang of Four — « programmez pour une interface, pas pour une implémentation » — pourrait se reformuler en termes platoniciens : attachez-vous à la Forme, pas à l'ombre sur la paroi de la caverne.

La programmation fonctionnelle pousse cette logique plus loin encore. En Haskell, une fonction pure comme add x y = x + y renvoie toujours le même résultat pour les mêmes arguments, sans effet de bord, sans dépendance au temps ou au contexte. Elle est éternelle, immuable, abstraite — les trois attributs que le platonisme mathématique prête aux objets mathématiques. La correspondance de Curry-Howard, découverte fondamentale du XXe siècle, établit que les types sont des propositions logiques et les programmes sont des preuves. Un programme de type A → B est littéralement une démonstration que A implique B. Logique, mathématiques et computation se révèlent être trois visages d'une même réalité — une idée dont la portée philosophique reste immense.

Typage nominal contre typage structurel : Duns Scot affronte Guillaume d'Ockham

L'une des manifestations les plus élégantes de la querelle médiévale se joue aujourd'hui dans l'opposition entre systèmes de types nominaux et structurels. En Java, deux classes possédant des champs et des méthodes identiques mais portant des noms différents sont considérées comme des types distincts. L'identité repose sur le nom déclaré, pas sur la structure interne. C'est la position de Duns Scot, qui posait que chaque chose possède une haeccéité — un principe d'individuation irréductible à ses propriétés — : deux entités de même nature peuvent être formellement distinctes.

En TypeScript ou en Go, au contraire, un objet satisfait une interface simplement en possédant les bonnes méthodes — sans aucune déclaration explicite d'appartenance. Si un type a la bonne structure, il est le bon type. C'est la victoire d'Ockham et du structuralisme : ne multipliez pas les entités au-delà du nécessaire ; ce qui compte, c'est la structure observable, pas le nom. Le fameux duck typing de Python — « si ça marche comme un canard et cancane comme un canard, c'est un canard » — incarne cette position avec un pragmatisme désarmant. L'essence cède la place au comportement.

Cette opposition n'est pas un accident d'ingénierie. Elle reflète une divergence philosophique profonde sur ce qui constitue l'identité. Le médiéviste reconnaîtra dans le typage nominal la via antiqua réaliste (Scot, Thomas d'Aquin) et dans le typage structurel la via moderna nominaliste (Ockham, Buridan). Sept siècles plus tard, les mêmes fractures ontologiques structurent nos langages de programmation.

Une ontologie d'un genre nouveau : l'artefact abstrait

Mais les abstractions informatiques se laissent-elles vraiment réduire aux catégories de la métaphysique classique ? Plusieurs philosophes contemporains en doutent. Timothy Colburn a forgé le concept d'« abstraction concrète » pour désigner la nature duale du logiciel : abstrait en tant que texte formel manipulable indépendamment de toute machine, concret en tant que processus physique s'exécutant sur un substrat matériel. Contrairement à l'abstraction mathématique, qui supprime du contenu, l'abstraction computationnelle le dissimule sans le détruire — chaque couche d'abstraction masque la complexité sous-jacente tout en la préservant intégralement.

Le philosophe Nurbay Irmak a poussé l'analyse plus loin en proposant que le logiciel constitue un « artefact abstrait » — une catégorie ontologique inédite. Un logiciel possède des propriétés temporelles (il est créé à un moment donné, peut cesser d'exister) mais pas de propriétés spatiales (il ne peut être identifié à aucune réalisation physique particulière). Si l'on détruisait toutes les copies d'un programme mais que quelqu'un se souvenait encore de son algorithme, le programme existerait-il toujours ? Irmak répond oui — comme une œuvre musicale survit à la destruction de toutes ses partitions tant qu'un musicien la connaît par cœur.

Raymond Turner, dans Computational Artifacts (2018), propose une troisième voie en traitant les programmes comme des artefacts techniques au sens de la philosophie de la technologie des entités définies simultanément par leurs propriétés fonctionnelles (ce qu'elles font) et structurelles (comment elles le font), organisées en niveaux d'abstraction hiérarchiques. Chaque niveau est à la fois fonctionnel pour le niveau inférieur et structurel pour le niveau supérieur — une dualité qui ne se résout jamais en un simple dualisme.

Ce que le code nous apprend sur la nature des abstractions

La programmation ne se contente pas d'illustrer des thèses métaphysiques préexistantes — elle en génère de nouvelles. Considérons le cas de null, inventé par Tony Hoare en 1965 et qu'il qualifiera plus tard d'« erreur à un milliard de dollars ». Philosophiquement, null est la représentation computationnelle de l'absence — et l'absence est ontologiquement glissante. Parménide affirmait que le non-être ne peut pas être pensé. Pourtant, null est quelque chose (il occupe de la mémoire, possède un type) qui représente rien. Haskell résout cette aporie avec le type Maybe a = Nothing | Just a, qui fait de l'absence un variant explicite du type plutôt qu'un trou dans l'ontologie — une solution qui aurait sans doute plu aux stoïciens.

Plus profondément, la pratique de la programmation révèle que l'abstraction n'est pas un appauvrissement mais un enrichissement. La mémoire virtuelle, par exemple, interpose entre le programme et la mémoire physique une couche d'abstraction qui n'enlève rien — elle ajoute de la portabilité, de la sécurité, de la simplicité. Chaque couche du système computationnel — du code source au langage machine, du système d'exploitation aux transistors — est simultanément « réelle » à son propre niveau. Il n'y a pas de niveau fondamental unique dont les autres seraient de pâles reflets. Cette architecture en niveaux évoque ce que Luciano Floridi appelle la méthode des niveaux d'abstraction : la réalité n'est pas numérique ou analogique en soi — elle apparaît comme l'un ou l'autre selon le niveau d'abstraction choisi par l'agent épistémique.

Quine écrivait qu'« être, c'est être la valeur d'une variable liée ». Les programmeurs vivent cette maxime au quotidien : déclarer let x: Int = 5, c'est littéralement lier une variable et, ce faisant, engager l'ontologie du programme à reconnaître l'existence des entiers. Les systèmes de types sont des théories ontologiques formalisées — ils décident ce qui existe, ce qui peut être dit, et ce qui est interdit.

Conclusion : programmer, c'est faire de la métaphysique appliquée

La programmation informatique accomplit quelque chose de remarquable : elle rend les questions métaphysiques opérationnelles. Le choix entre typage nominal et structurel n'est pas seulement une décision technique — c'est une prise de position sur la nature de l'identité. La conception d'une hiérarchie de classes est un exercice de taxonomie ontologique. L'écriture d'une fonction pure est un acte de foi platonicienne.

Mais l'enseignement le plus profond est peut-être celui-ci : les abstractions informatiques ne rentrent dans aucune case métaphysique préexistante. Elles ne sont ni purement platoniciennes (elles sont créées, pas découvertes), ni purement nominalistes (elles ont une efficacité causale réelle), ni simplement mentales (elles survivent à leurs créateurs). Elles constituent une catégorie ontologique originale — des artefacts abstraits, temporels mais non spatiaux, formels mais causalement efficaces — qui enrichit notre compréhension de ce que « exister » peut vouloir dire. En écrivant du code, nous ne manipulons pas seulement des abstractions : nous explorons, à chaque ligne, les frontières de l'être.

Suivant
Suivant

Quand le fini engendre l'infini : récursion et vertige de l'illimité