4 points par GN⁺ 13 일 전 | 1 commentaires | Partager sur WhatsApp
  • Née dans le chaos logiciel du département de la Défense américain dans les années 1970, Ada est un langage dont les principes centraux sont le typage statique fort et la séparation entre spécification et implémentation
  • Grâce à sa structure en packages et à l’opacité de représentation, elle met en œuvre une encapsulation complète et a ensuite influencé les systèmes de modules de langages modernes comme Java, C# et Go
  • Les types à contraintes sémantiques, les génériques, la concurrence (task) et la conception par contrat sont autant de concepts qu’Ada a proposés avec plusieurs décennies d’avance, avant d’être repris par Haskell, Rust ou Swift
  • SPARK Ada élimine même les courses de données et les erreurs logiques par vérification formelle, et est utilisé dans des domaines à haute fiabilité comme l’aéronautique, le ferroviaire et les systèmes de défense
  • Ada n’est pas un langage populaire, mais il reste un « langage qui fonctionne correctement en silence », ayant posé les principes fondamentaux de la conception des langages de programmation modernes

Contexte de naissance d’Ada et philosophie de conception

  • Au début des années 1970, le département de la Défense des États-Unis (DoD) étudie une situation où plus de 450 langages et dialectes coexistent dans les systèmes d’armement, de logistique et de communication
    • Chaque système souffre de problèmes d’interopérabilité, de maintenance impossible ou de disparition de l’auteur initial
    • Cela provoque une crise des achats logiciels
  • Le DoD n’adopte pas un langage existant (COBOL, Fortran, PL/1, etc.) et passe par un processus de définition des exigences sur cinq ans
    • Strawman → Woodenman → Tinman → Ironman → Steelman
    • Steelman (1978) exige une séparation explicite des interfaces, un typage statique fort, une concurrence intégrée, une gestion cohérente des exceptions, l’indépendance vis-à-vis de la machine, la lisibilité et la vérifiabilité
  • En 1979, lors de la compétition entre quatre équipes (Green, Red, Blue, Yellow), l’équipe Green dirigée par Jean Ichbiah est retenue, et le langage reçoit le nom de Ada
    • Ce nom rend hommage à Ada Lovelace et symbolise l’intention du langage

Structure en packages et encapsulation

  • La structure centrale d’Ada est le package, avec une séparation physique entre la spécification (specification) et le corps (body)
    • La spécification est le contrat exposé à l’extérieur, le corps est l’implémentation, et le compilateur impose la relation entre les deux
    • Le code client ne peut pas accéder aux éléments absents de la spécification
  • Cette structure constitue un prototype de système de modules, que des langages ultérieurs n’ont imité que partiellement
    • Java, Python, JavaScript, C, Go et Rust ne mettent pas tous en œuvre la séparation structurelle complète d’Ada
  • Les types private n’exposent que leur nom, tandis que leur représentation interne reste totalement opaque
    • Le client ne peut pas connaître la structure interne du type et ne peut utiliser que les opérations autorisées
    • C’est une opacité de représentation plus forte que le contrôle d’accès private de Java
  • Java et C# ont évolué progressivement pendant des décennies vers un niveau d’encapsulation proche de celui d’Ada

Système de types et contraintes sémantiques

  • Ada définit mathématiquement la distinction entre type et sous-type
    • Exemple : type Age is range 0 .. 150 crée un type distinct doté d’une contrainte d’intervalle
    • Le passage entre types incompatibles est détecté comme erreur à la compilation
  • En 1983, le système de types d’Ada était bien plus expressif que ceux de C, Fortran ou Pascal
    • Les types à contraintes sémantiques permettent d’éviter des erreurs métier
  • Le record discriminé (discriminated record) est une structure qui possède des champs différents selon la valeur
    • Cela correspond aux sum types modernes ou aux types de données algébriques (ADT)
    • Haskell, Rust, Swift, Kotlin et TypeScript ont introduit le même concept plusieurs décennies plus tard

Génériques et polymorphisme

  • Les génériques d’Ada sont des unités pouvant prendre comme paramètres des types, des valeurs, des sous-programmes et des packages
    • Ils implémentent un polymorphisme statique (parametric polymorphism) avec vérification des types à la compilation
  • C++ (1990), Java (2004), C# (2005) et Go (2022), entre autres, n’ont introduit des fonctions similaires que plusieurs décennies après Ada
    • Java, avec le type erasure, perd l’information de type à l’exécution
    • Ada conserve les types à l’exécution et prend même en charge la paramétrisation de packages
  • Les génériques d’Ada offrent une expressivité proche du polymorphisme d’ordre supérieur (higher-kinded polymorphism)
    • Un concept comparable aux type classes de Haskell, aux traits de Rust et aux concepts de C++20

Modèle de concurrence et sûreté

  • Ada intègre dès 1983 la concurrence au niveau du langage avec les task
    • La déclaration de task et le modèle de communication par rendezvous mettent en œuvre une transmission de messages sans état partagé
    • Les channels de Go relèvent de la même famille de concepts CSP (Communicating Sequential Processes)
  • Ada 95 introduit les protected objects
    • Ils protègent l’accès aux données, avec une distinction entre procedure, function et entry
    • Ils fournissent des conditions de garde automatiques et une synchronisation sans verrou
  • SPARK Ada démontre formellement l’absence de courses de données, d’exceptions, d’erreurs de plage et de violations de préconditions ou de postconditions
    • Alors que le borrow checker de Rust ne garantit que la sûreté mémoire, SPARK va jusqu’à prouver la cohérence logique

Conception par contrat et sûreté vis-à-vis de null

  • Ada 2012 intègre les contrats directement dans le langage
    • Il permet d’exprimer des préconditions, des postconditions et des invariants de type
    • La chaîne d’outils SPARK les exploite pour la preuve statique
  • Il formalise au niveau du langage le concept de Design by Contract d’Eiffel (1986)
    • C++, Java, Python et Rust n’en proposent que des implémentations partielles ou limitées à des bibliothèques
  • Ada 2005 introduit les types not null afin de prendre en charge l’exclusion de null à la compilation
    • Par défaut, l’échec reste sûr via une exception à l’exécution (Constraint_Error)
    • Une approche comparable aux références nullable de C# 8.0

Structure de gestion des exceptions

  • Ada 83 introduit pour la première fois la gestion structurée des exceptions (structured exception handling)
    • Les exceptions sont déclarées avant utilisation, traitées selon leur portée, avec des règles de propagation explicites
  • Les checked exceptions de Java constituent une forme plus avancée, où l’appelant doit déclarer les exceptions
    • Ada autorise librement la propagation des exceptions
  • Rust supprime les exceptions et adopte une gestion des erreurs fondée sur le type Result
    • La contribution d’Ada est d’avoir rendu la propagation des exceptions structurée et prévisible

Annexes et structure de normalisation

  • La norme Ada comporte une structure d’extensions optionnelles appelée Annex
    • Les annexes C à H définissent des fonctionnalités par domaine : système, temps réel, distribué, calcul numérique, haute fiabilité
    • Les compilateurs doivent obtenir une certification indépendante pour chaque annexe
  • La conformité à la norme est vérifiée par les tests ACATS de l’ACAA
    • La structure normalisée d’Ada peut être utilisée directement pour la certification logicielle aéronautique DO-178C
    • C et C++ peuvent eux aussi être certifiés, mais Ada y est structurellement mieux adapté

Influence d’Ada et décalage de perception

  • Ada, en tant que langage porté par les pouvoirs publics, n’a pas retenu l’attention de la culture Silicon Valley
    • Il contraste avec une culture préférant des syntaxes concises issues de C
  • Les réussites d’Ada (aéronautique, ferroviaire, systèmes de défense) ont une faible visibilité précisément parce qu’elles n’échouent pas
    • Un système très fiable ne génère ni polémiques ni incidents
  • L’évolution des langages modernes converge vers des principes qu’Ada avait déjà formulés
    • Séparation spécification-implémentation, vérification statique des types, concurrence au niveau du langage, sûreté fondée sur le contrat, etc.
  • Ada est toujours utilisé dans des systèmes à haute fiabilité comme les avions, les chemins de fer ou les engins spatiaux, et demeure un « langage qui fonctionne correctement en silence »

1 commentaires

 
GN⁺ 13 일 전
Avis Hacker News
  • J’aime Ada. Mais en parlant de gestion des types, je suis surpris que les langages de la famille ML (ML, SML, CML, Caml, OCaml, etc.) soient complètement passés sous silence
    Ces langages prennent en charge les types structurels au niveau du compilateur. Le problème d’Ada, comme PL/I, PHP ou Perl, c’est que le langage lui-même était trop vaste et sa grammaire trop complexe. L’article présente cela comme un avantage, mais personnellement, je trouve que les extensions standard séparées en annexes étaient bien meilleures. Si le langage cœur avait été plus petit et orienté autour des annexes, il aurait sans doute été plus largement adopté

    • Dans les langages ML, l’utilisateur ne peut pas définir lui-même des types entiers/flottants bornés. C’est justement l’une des fonctionnalités centrales d’Ada. Quand on découvre le système de types d’Ada, on est surpris de voir à quel point il peut améliorer la qualité et la fiabilité du code
  • L’une des raisons pour lesquelles Ada a été boudé, c’est que les compilateurs coûtaient des dizaines de milliers de dollars. À l’époque où il n’existait ni compilateur gratuit ni open source, les autres langages étaient disponibles sans frais. Ça a été un facteur décisif

    • Si Ada n’est jamais sorti de sa niche, c’est à cause d’un ensemble de facteurs. La complexité du langage, combinée à l’état de la technologie des compilateurs de l’époque, faisait qu’il tournait mal sur les micro-ordinateurs des années 1980. Intel a bien essayé d’intégrer les concepts d’Ada dans le matériel avec l’i432, mais les performances étaient catastrophiques. Ensuite, les micro-ordinateurs ont pris le dessus, et l’héritage du C et de l’assembleur a perduré pendant plus de 20 ans
    • J’ai utilisé Ada pendant quelques années, et le fait que mes collègues pratiquaient d’autres langages comme hobby n’a pas aidé à sa diffusion. Le traitement des chaînes était faible, et les performances étaient lentes. En particulier, la gestion de la concurrence était peu pratique parce qu’elle n’utilisait pas les threads de l’OS. Au final, on utilisait l’extension temps réel de HPUX pour faire tourner plusieurs processus
    • Il y avait GNAT dès le milieu des années 1990, et à cette époque les compilateurs commerciaux étaient aussi courants. Si Ada a bloqué, c’est à cause de la perception d’un « surcoût inutile ». En clair, il avait la réputation de n’avoir d’intérêt que pour le militaire ou les systèmes critiques
    • GNU Ada Compiler (GNAT) a été publié pour la première fois en 1995
    • En réalité, dans les années 1980, la qualité des compilateurs laissait à désirer quel que soit le langage. Même GCC n’est devenu vraiment utilisable que sur la fin. Quand on adoptait un nouveau langage, il était normal que le compilateur soit immature. C++ aussi était très en retard sur Ada à l’époque, et sa « fonctionnalité tueuse » était en pratique qu’on pouvait l’utiliser comme du C. Si Ada avait proposé un mode de compatibilité Pascal, l’histoire aurait peut-être été différente
  • En lisant l’article, j’ai trouvé Ada intéressant, tout comme le texte lui-même, mais quelques erreurs factuelles m’ont sauté aux yeux. Par exemple, il affirmait que seul Ada séparait complètement implémentation et spécification, alors qu’en JavaScript aussi on peut définir des éléments privés avec les modules ES6. L’explication de la visibilité private en Java était également erronée. Ce genre d’erreurs nuit à la crédibilité du texte

    • En Ada, quand on définit un type private, il est impossible d’accéder à ses champs internes depuis l’extérieur. En revanche, en JavaScript, on peut librement ajouter ou supprimer des propriétés à n’importe quel objet. Le niveau de protection à la compilation d’Ada est donc sans commune mesure avec celui de JS
    • En Java, on peut accéder à des membres privés via la reflection. Avec setAccessible(true), on peut même modifier l’intérieur d’un String
    • J’ai trouvé marquante l’idée que quand un LLM écrit pour des lecteurs humains, cela fonctionne un peu comme la Gell-Mann amnesia
  • Dans l’ensemble, le texte était bon, mais la répétition continuelle de phrases du type « le langage X a acquis cette fonctionnalité après Ada » devenait lassante. Avec des exemples de code, cela aurait été bien plus convaincant

    • En réalité, beaucoup de fonctionnalités d’Ada étaient empruntées à des langages antérieurs (PASCAL, CLU, MODULA, CSP, etc.). Ce n’était pas tant des concepts entièrement nouveaux qu’une intégration d’idées déjà éprouvées
    • Parmi les concepts que l’article affirme introduits d’abord par Ada, certains étaient en fait implémentés différemment ailleurs. D’où le besoin d’exemples comparatifs
    • Ce texte ne dit pas « Ada est le meilleur », il montre plutôt quels choix de conception Ada a faits pour la sûreté et la fiabilité. La comparaison chronologique a du sens dans ce contexte
    • J’ai demandé à Claude de produire du code de démonstration en Ada, et le résultat était plutôt bon. Je connaissais Ada depuis longtemps, mais en l’essayant moi-même, j’ai ressenti du FOMO
    • Du point de vue d’un développeur Ada, ce genre de schéma comparatif répété depuis des décennies peut aussi devenir fatigant
  • Ce compte Twitter a été créé en avril 2026 et n’indique pas d’auteur. Il a montré une productivité énorme sur une très courte période, et le fait que le nom de l’auteur ne soit pas affiché est intrigant

    • Certains pensent que l’absence d’auteur s’explique par le fait qu’il s’agit d’un bot
  • L’affirmation selon laquelle « tous les langages ont ajouté les sum types au cours des 20 dernières années, alors qu’Ada les avait dès le départ » est vraie, mais leur origine ne vient pas d’Ada. Le langage Hope ou NPL les avaient déjà avant

    • En fait, l’origine des sum types remonte à l’article de John McCarthy de 1964, “Definition of new data types in ALGOL X”. Il y proposait le mot-clé UNION, qui a ensuite évolué dans ALGOL 68, Hope, Miranda, etc. Le union du C est autre chose
  • J’ai tellement aimé l’article que j’espérais qu’il n’était pas écrit par une IA, mais le rythme de publication sur Twitter était si rapide que ça m’a rendu méfiant

    • Le texte avait un côté un peu verbeux et répétitif, ce qui donnait une impression d’IA
    • Aujourd’hui, il existe beaucoup d’outils d’IA qui réécrivent automatiquement des billets de blog, ce qui alimente le doute
    • J’ai moi aussi lu l’article avec plaisir, mais après avoir compté 110 tirets cadratins, je me suis dit : « et si c’était de l’IA ? ». C’est triste d’en être arrivé à lire même les billets de blog avec une forme de littératie médiatique
    • Moi aussi, j’ai écrit 50 textes en 3 ans, mais la plupart ne sont pas publiés. Peut-être que cet auteur était dans une situation similaire et a simplement trouvé le courage de publier récemment. Je comprends à quel point être pris à tort pour une IA peut être frustrant
    • Si une IA est capable d’écrire à ce niveau, alors cela vaut la peine d’y consacrer du temps
  • L’US Air Force voulait à l’origine utiliser Ada, mais comme le développement a pris du retard, elle a utilisé JOVIAL. J’ai réalisé mon premier projet en JOVIAL en 1981, et à l’époque Ada n’en était encore qu’au stade des spécifications

    • JOVIAL était un langage dérivé de l’IAL, précurseur d’ALGOL 60, et il a influencé les premières exigences du développement d’Ada (STRAWMAN à STEELMAN). Ada a ensuite amélioré certaines fonctionnalités de JOVIAL et introduit des innovations comme la déclaration explicite des paramètres in/out. Grâce à cela, il n’avait pas besoin de constructeurs de copie ni de move semantics complexes comme en C++
  • Sur la page principale du site, on peut lire la phrase « ce n’est pas une position, c’est une proposition », et certains s’en servent pour affirmer qu’il s’agit d’un site écrit par IA

    • Mais cette phrase ne constitue pas une preuve d’une rédaction par IA
  • L’article disait que « le système de modules de JavaScript ne peut pas cacher la représentation interne d’un type comme Ada », mais en réalité, dans les modules JS, si quelque chose n’est pas exporté, c’est parfaitement caché. Je me demandais donc en quoi Ada était réellement meilleur sur ce point

    • Si l’on prend TypeScript comme référence, les objets JS peuvent toujours recevoir de nouvelles propriétés ou être modifiés depuis l’extérieur. En Ada, il est impossible de manipuler une instance de type private autrement que via l’API définie
    • On peut voir un exemple concret dans ce commentaire