2 points par GN⁺ 2023-07-18 | 1 commentaires | Partager sur WhatsApp
  • Forth est né comme un petit interpréteur conçu par Chuck Moore pour réduire les longs cycles compilation-cartes perforées, avant d’évoluer en un système absorbant jusqu’à l’éditeur, le système d’exploitation et le compilateur
  • La notation postfixée (RPN), la pile de données et les mots (dictionary) n’étaient pas une syntaxe étrange, mais une conception pensée pour réduire le gaspillage et les tâches répétitives sur un matériel très contraint
  • Le cœur de Forth réside dans une structure bootstrapable où l’on peut définir et redéfinir à l’intérieur même du langage des éléments comme :, ;, IF, les commentaires ou les variables
  • Des implémentations comme JonesForth, nasmjf, PlanckForth et sectorforth montrent que Forth peut partir de quelques dizaines à quelques centaines d’octets, ou d’un petit nombre de primitives, puis s’étendre en interpréteur, compilateur, assembleur ou DSL
  • Les cas des vaisseaux spatiaux, d’Open Firmware, du Jupiter Ace, du Canon Cat, du Harris RTX2010 et de GreenArrays montrent que Forth est étroitement lié au développement interactif, à la compacité du code, à l’affinité avec le matériel et au calcul basse consommation

Point de départ : d’une légende d’Usenet à une exploration de Forth

  • Dave Gauer a retracé son parcours personnel de découverte de Forth et de sa mise en perspective dans l’histoire de l’informatique, et cette page est adaptée d’un court jeu de diapositives de présentation
  • Dans les années 1990, les groupes comp.* d’Usenet, en particulier comp.lang.*, étaient un lieu important pour apprendre et débattre de programmation
    • La toute première annonce de Linux par Linus Torvalds est aussi citée comme un exemple publié en 1991 sur comp.os.minix
    • À la fin des années 1990, Perl occupait une place majeure sur le Web des débuts comme langage de traitement des formulaires et de pages dynamiques via CGI
  • Les légendes croisées à l’époque d’Usenet, comme les langages de la famille Lisp, le combinateur Y, The Little Schemer ou The Story of Mel, ont nourri cette curiosité pour Forth
  • Forth s’est d’abord présenté comme un langage dont on disait qu’il était « assez flexible pour changer la valeur des entiers », et Chuck Moore restait dans les mémoires comme un « mad wizard » capable d’écrire n’importe quel programme en quelques écrans de code
  • La série de billets de blog de James Hague, programming in the twenty-first century, a constitué le dernier déclic vers l’exploration de Forth

La RPN et la pile ne sont qu’un point de départ

  • La première impression donnée par Forth est celle de la notation postfixée ou Reverse Polish Notation (RPN)
    • Contrairement à la notation infixée classique 3 + 4, Forth place l’opérateur après les opérandes, comme dans 3 4 +
    • L’exemple Forth 3 4 * 5 6 * + . affiche 42
    • Dans dc, le même calcul s’écrit 3 4 * 5 6 * + p
  • La RPN permet d’évaluer des expressions imbriquées dans l’ordre voulu sans parenthèses
    • 3 4 * produit 12, 5 6 * produit 30, puis le + final produit 42
    • En Forth, . dépile une valeur et l’affiche
  • La calculatrice HP-35 est un exemple historique important de la diffusion de la RPN au-delà de l’informatique
    • Au début des années 1970, HP disposait déjà de puissantes calculatrices de bureau, et la HP-35 est présentée comme le cas où cette puissance de calcul a été mise dans une calculatrice de poche « shirt pocket »
    • Les calculatrices HP étaient célèbres pour leur syntaxe RPN, efficace mais un peu déroutante pour les non-initiés
  • La deuxième caractéristique est la pile de données
    • Des opérations comme PUSH, POP, SWAP et DUP sont aussi des words Forth
    • Quand on saisit un nombre, il est empilé ; les opérateurs dépilent des valeurs, calculent, puis réempilent le résultat
  • La pile réduit le besoin de donner des noms aux valeurs intermédiaires
    • Dans beaucoup de langages impératifs, il faut des noms temporaires comme result2 ou matched_part3
    • Cette manière de travailler sans noms est aussi appelée programmation implicite, tacite ou point-free
    • Comprendre Forth uniquement à travers la RPN et la pile est insuffisant, mais cela reste un point de départ valable pour en saisir les origines historiques

Programmation concatenative, Joy, et ce qui le distingue de Forth

  • En explorant Forth, on rencontre vite la notion de programmation concatenative
    • Un exemple applicatif serait eat(bake(prove(mix(ingredients))))
    • Un exemple concatenatif serait ingredients mix prove bake eat
    • Les fonctions sont énumérées dans l’ordre, et la valeur de chaque étape est transmise implicitement à la suivante
  • Joy est un exemple représentatif de langage concatenatif
    • Manfred von Thun s’est inspiré de la conférence Turing Award de l’ACM donnée par John Backus en 1977, « Can Programming Be Liberated from the von Neumann Style? »
    • Dans Joy, toute fonction prend une pile en entrée et renvoie une pile en sortie
    • Un programme y est une liste de fonctions lue de gauche à droite
  • Les quotations et combinateurs de Joy montrent une manière de calculer sans variables
    • En JavaScript, [1, 2, 3, 4].map(n => n + 1) produit [2,3,4,5]
    • Dans Joy, on obtient le même résultat avec [1 2 3 4] [1 +] map
    • Dans Joy, [] est un mécanisme de quotation qui peut contenir non seulement des données, mais aussi des programmes
  • Un combinateur est traité comme une fonction d’ordre supérieur qui prend d’autres fonctions en entrée
    • map() est un exemple d’abstraction du code récurrent de parcours de liste
    • Les combinateurs I, K, S et le calcul SKI apparaissent comme une construction permettant d’expliquer le calcul universel
    • S et K suffisent à eux seuls à former un système complet pour le calcul universel
  • Forth permet lui aussi de créer des fonctions d’ordre supérieur grâce aux execution tokens et au word EXECUTE
    • FOO EXECUTE exécute le word renvoyé par le word FOO
    • On peut définir des words combinatoires comme MAP, FOLD ou REDUCE
  • Forth et Joy ont une syntaxe de surface similaire, mais interprètent les expressions différemment
    • En Forth, 2 3 + se lit comme « empiler 2 et 3, puis additionner »
    • En Joy, cela se lit plutôt comme « la composition des fonctions 2, 3 et + équivaut à la fonction 5 »
    • Forth est moins un langage issu de principes abstraits du calcul concatenatif qu’un langage ayant grandi au contact direct du matériel

Le parcours de Chuck Moore vers la création de Forth

  • En 1958, Chuck Moore utilise Fortran et l’IBM 704 pendant son passage au Smithsonian Astrophysical Observatory et au MIT
    • Dans Forth, the Early years, Moore dit : « Compiling took 30 minutes...you got one shot per day »
    • L’IBM 704 était un ordinateur à tubes à vide qui remplissait une pièce, et une citation précise aussi qu’il tombait en panne en moyenne toutes les 8 heures environ
  • Pour réduire les recompilations, Moore crée un interpréteur simple qui lit des cartes contrôlant le programme
    • Cela permettait de composer différentes équations pour plusieurs satellites sans recompile
    • Le format d’entrée libre était plus fiable pour les humains à écrire que les colonnes formatées de Fortran
    • Ce système devient plus tard l’origine de ce qui sera appelé Forth
  • En 1961, à Stanford, Moore utilise un Burroughs B5500 et écrit une application mathématique appelée CURVE
    • CURVE comprend un interpréteur plus sophistiqué, une pile de données et des opérateurs de contrôle de flux
    • Les fonctionnalités correspondent en gros à des words Forth comme IF ELSE DUP DROP SWAP + - *
    • Avec l’ajout d’une pile de paramètres et de la définition de nouvelles procédures, on voit apparaître une structure proche de Forth
  • Vers 1965, avec l’arrivée des teletypes, des bandes perforées, du timesharing et des terminaux interactifs, Forth devient plus interactif
    • Des words comme KEY, EMIT, CR, SPACE, DIGIT sont ajoutés
    • Ces words transforment le système de Moore en éditeur de programmes, et l’utilisateur peut éditer un programme depuis l’intérieur du programme
  • En 1968, chez Mohasco, Moore travaille sur un IBM 1130 et lui donne le nom de « FORTH »
    • L’IBM 1130 était une machine 16 bits avec 8 KB de RAM, et les noms de fichiers étaient limités à 5 caractères
    • Le système « fourth generation » de Moore devient FORTH à cause de cette limite à 5 caractères
    • À cette période, la pile d’appels de retour et le dictionnaire de words sont ajoutés
  • Le dictionnaire nommé de words de Forth sert d’abstraction principale
    • : DOUBLE DUP + ;
    • : QUAD DOUBLE DOUBLE ;
    • Sans pile de retour, impossible après l’exécution de DOUBLE de revenir à l’emplacement restant de QUAD

NRAO, portage et indirect threaded code

  • Au début des années 1970, Moore écrit au National Radio Astronomy Observatory des logiciels de contrôle informatique pour des radiotélescopes
    • Le NRAO avait pour politique d’utiliser Fortran sur minicomputer, mais Moore obtient l’autorisation d’utiliser Forth grâce à ses succès précédents
    • En spectral-line observing, il était possible d’afficher les spectres en cours d’acquisition et d’ajuster les formes de raies par least-squares
    • Ce travail a fait progresser l’état de l’art de la réduction de données en ligne, et les astronomes l’ont utilisé pour découvrir et cartographier des molécules interstellaires
  • Elizabeth « Bess » Rather adopte Forth et rédige en 1972 le premier manuel Forth
    • Elle cofonde ensuite FORTH, Inc avec Chuck Moore
    • Jusqu’à sa retraite en 2006, elle reste l’une des principales expertes et promotrices du langage Forth
  • Forth est porté sur plusieurs machines, dont l’IBM 360/50, le Honeywell 316, le Honeywell DDP-116 et le DEC PDP-11
    • L’implémentation Forth pour le H316 a été programmée sur l’ordinateur lui-même puis utilisée pour en créer d’autres, ce qui en fait la première implémentation complète et autonome
    • Le PDP-11 est un minicomputer important, lié à l’histoire d’Unix et du langage de programmation C
  • La possibilité de porter Forth sur plusieurs machines tient notamment à l’indirect threaded code
    • Ici, threaded code n’a rien à voir avec la concurrence ni avec la programmation multi-thread
    • Le threaded code stocke une liste d’adresses de sous-routines au lieu d’instructions d’appel de sous-routine
    • L’exécution de cette liste d’adresses nécessite un interpréteur de code
  • L’indirect threaded code ne stocke pas des adresses pointant directement vers le code, mais une liste d’adresses pointant vers des adresses qui pointent vers le code
    • Cette seconde indirection permet d’avoir un inner interpreter distinct selon les différents types de sous-routines
    • En Forth, l’outer interpreter est la partie avec laquelle l’utilisateur interagit dans le terminal, tandis que l’inner interpreter exécute le reste des words
  • À ce stade, Forth dépasse le simple interpréteur de commandes pour devenir un langage interactif, un éditeur, un système d’exploitation, ainsi qu’une méthode de stockage et d’exécution du code
    • Ses caractéristiques sont alors résumées ainsi : notation postfixée, orienté pile, style concaténatif, interprété, highly adaptable à l’architecture machine, et extrêmement compact
    • Forth n’est pas un langage conçu d’un seul coup en 1958, mais le résultat d’une croissance continue par Moore selon ses besoins et l’évolution du hardware

Pour comprendre Forth, il faut implémenter un Forth

  • Dans le conseil « To understand Forth, you have to implement a Forth », le mot important est a Forth
    • Du point de vue de Chuck Moore, un système Forth est meilleur quand il est custom-tailored au système et à la tâche
  • Avant de se plonger dans le code source de JonesForth, l’auteur a écrit Assembly Nights pour apprendre les bases de l’assembly et de l’ABI Linux
    • JonesForth utilise du code source assembly i386 écrit pour l’assembleur GNU GAS
    • Il est réservé au 32-bit et utilise directement l’ABI des appels système Linux
    • L’auteur a passé environ un an à porter JonesForth vers une copie fonctionnant avec l’assembleur NASM, et ce port s’appelle nasmjf
  • Pendant le portage de nasmjf, il a appris le fonctionnement du Forth indirect threaded traditionnel
    • Le jonesforth.S de JonesForth est un fichier unique contenant la partie assembly, et Richard W.M. Jones y guide le lecteur dans le flux de l’interpréteur avec de l’ASCII art et des explications
    • Pour clarifier sa propre compréhension, l’auteur a ajouté plusieurs diagrammes en ASCII art dans le code source de nasmjf
  • La macro NEXT constitue le flux central qui fait passer d’un word au suivant après l’exécution d’un word
%macro NEXT 0
    lodsd     ; NEXT: Load from memory into eax, inc esi to point to next word.
    jmp [eax] ; Jump to whatever code we're now pointing at.
%endmacro
  • lodsd déplace un double word de la mémoire vers eax et met à jour le pointeur vers la position suivante
  • jmp [eax] transfère l’exécution vers l’emplacement actuellement pointé, ce qui devient l’inner interpreter de cette sous-routine
  • Dans le Forth traditionnel, on trouve essentiellement des code words et des colon words
    • Les code words sont des primitives écrites en code machine
    • Les colon words sont des words ordinaires écrits en langage Forth et assemblés par le compilateur :
    • Un colon word se termine par EXIT, et EXIT traite la pile de retour avant de poursuivre le flux avec NEXT
  • Forth repose sur de très petits éléments qui coopèrent pour former un système en fonctionnement
    • À bas niveau, cela apporte flexibilité et simplicité, mais à plus haut niveau, cela peut se payer par une moindre facilité de compréhension

Les code words, les colon words et le compilateur fonctionnent sur le même interpréteur

  • SWAP, DUP et DROP montrent à quel point les primitives de Forth peuvent être implémentées directement en code machine
DEFCODE "SWAP",SWAP,0
    pop eax
    pop ebx
    push eax
    push ebx
NEXT
DEFCODE "DUP",DUP,0
    mov eax, [esp]
    push eax
NEXT
DEFCODE "DROP",DROP,0
    pop eax
NEXT
  • JonesForth utilise la pile d’appel/retour i386 comme pile de paramètres Forth, et implémente donc les opérations de pile avec les instructions natives pop et push
  • nasmjf contient 130 code words, dont la plupart existent pour des raisons d’efficacité
    • il existe un minimum théorique du nombre de words en code machine nécessaires à un système Forth bootstrappable
    • réduire excessivement le nombre de primitives peut rendre le reste du code Forth inefficace et tordu
    • A 3-INSTRUCTION FORTH FOR EMBEDDED SYSTEMS WORK de Frank Sergeant traite d’un Forth à 3 instructions ne nécessitant que 66 octets sur Motorola MC68HC11
    • sectorforth est un Forth x86 16 bits qui tient dans un secteur de boot de 512 octets
  • un colon word est une manière de créer un nouveau word comme composition de words existants
: SDD SWAP DROP DUP ;
  • SDD a le même effet que d’appeler SWAP DROP DUP dans cet ordre
  • du point de vue de l’indirect threaded code, un colon word est compilé comme les adresses de l’interpréteur interne de trois code words
  • : et ; ressemblent à de la syntaxe, mais ce sont en réalité des words Forth
    • : prend le nom du nouveau word et active le mode compilation
    • ; termine la nouvelle entrée du dictionnaire et désactive le mode compilation
    • l’utilisateur peut remplacer : lui-même par sa propre définition pour étendre ou modifier Forth
    • l’unique syntaxe de Forth repose sur les espaces entre les tokens d’entrée
  • dans Forth, compiler consiste à placer en mémoire l’adresse d’un word, ou bien un littéral et le code qui le pousse sur la pile
    • en mode normal, le word est exécuté immédiatement
    • en mode compilation, l’adresse du word est stockée en mémoire
    • le même interpréteur sert à la fois à exécuter le code et à compiler le code
  • des structures de contrôle comme IF...THEN peuvent elles aussi être implémentées dans Forth lui-même
: IF IMMEDIATE ' 0BRANCH , HERE @ 0 , ;

: THEN IMMEDIATE DUP HERE @ SWAP - SWAP ! ;
  • le fait qu’un élément aussi fondamental que IF soit défini à l’intérieur du langage est au cœur du titre « The programming language that writes itself »
  • même le commentaire imbriqué ( ... ) est implémenté en Forth dans jonesforth.f
    • même les commentaires sont implémentés dans le langage, et l’utilisateur peut les redéfinir ou ajouter sa propre manière de commenter
    • cet exemple souligne que Forth n’a presque pas de syntaxe native

Le dictionnaire et la redéfinition créent l’extensibilité

  • le dictionnaire Forth utilise traditionnellement une liste chaînée, et la correspondance des mots commence par l’entrée la plus récente
    • la définition la plus récente d’un mot portant le même nom masque la définition précédente
    • n’importe quel word peut être redéfini, y compris un word initialement défini en assembleur
    • les words déjà compilés stockent des adresses et non des noms, ils continuent donc à pointer vers l’adresse du word d’avant la redéfinition
  • on peut étendre un word en appelant, dans une nouvelle définition, le word précédent portant le même nom
    • pour créer un word récursif, : cache dans le dictionnaire le word en cours de compilation, ou le marque comme inactif
    • pour s’appeler lui-même à l’intérieur du word courant, il faut RECURSE
  • l’exemple de variable de pommes repris et modifié depuis Thinking Forth de Leo Brodie montre la souplesse de Forth
    • VARIABLE APPLES crée le word APPLES, qui pousse une adresse mémoire sur la pile lorsqu’il est appelé
    • 20 APPLES ! stocke 20 à cette adresse
    • APPLES ? récupère la valeur et l’affiche
    • Thinking Forth (PDF) est disponible gratuitement
  • même s’il faut suivre séparément les pommes rouges et les pommes vertes, il n’est pas nécessaire de modifier le code existant qui utilise APPLES
VARIABLE COLOR

VARIABLE REDS
: RED REDS COLOR ! ;

VARIABLE GREENS
: GREEN GREENS COLOR ! ;

: APPLES COLOR @ ;
  • le nouveau APPLES est lui aussi un word qui pousse une adresse sur la pile, l’usage existant de APPLES ! et APPLES ? reste donc inchangé
  • seule l’adresse bascule entre REDS et GREENS selon la couleur de pomme active
  • vu depuis un langage classique, on pourrait croire qu’une variable s’est transformée en fonction, mais dans Forth les variables sont aussi des words qui poussent des adresses, et les fonctions sont elles aussi des words, donc il n’y a pas de changement de concept au niveau du langage
  • même un token qui ressemble à un nombre peut être redéfini comme word du dictionnaire
: 4 12 ;
  • si l’on exécute ." The value of 4 is " 4 . CR, la sortie sera The value of 4 is 12

Meow5 et Forth comme « chemin de moindre résistance »

  • nasmjf, portage en NASM de JonesForth, n’était pas une reproduction du processus de Moore, mais plutôt un exercice proche d’une « master copy » obtenue par observation attentive du produit final
  • l’auteur a ensuite mené une expérience extrême de programmation concaténative appelée Meow5
    • Meow5 est une expérience où tout le code est toujours concaténé et inline
    • comme Forth, il utilise le concept de pile de paramètres, il est donc concaténatif
    • c’était une expérience de pensée poussant l’idée suivante : que se passerait-il si, au lieu de stocker des adresses d’appel de fonctions, on stockait une copie complète de la fonction
  • le cœur de Meow5 consistait à rendre tous les words 100 % inline
    • le point de départ était l’inline expansion, optimisation courante qui évite le petit surcoût des appels de fonction
    • appeler, via plusieurs sauts, une primitive d’une seule instruction comme DROP semblait être du gâchis
  • Meow5 s’est terminé en « joyeux petit échec »
    • l’inlining du code machine en lui-même fonctionnait bien, et les exécutables ELF générés se comportaient comme prévu
    • le problème venait des données de chaîne de caractères : il fallait soit recopier les chaînes à chaque fois, soit suivre de manière complexe quels words utilisaient une chaîne
    • le word INLINE de Forth, qui permet un inlining sélectif, a été jugé meilleur
  • la syntaxe des chaînes a elle aussi confirmé le conseil de Moore
    • dans Forth, on utilise le word ", ce qui impose un espace comme dans " Hello World."
    • Meow5 a adopté un style de guillemets plus naturel, de la forme "Hello World.", ainsi que des séquences d’échappement comme \n et \"
    • ce choix a obligé à gérer des cas particuliers pour " dans le tokenizer et l’interpréteur, ce qui a réduit la pureté et la simplicité
  • dès qu’on commence à suivre la voie de Forth, le reste s’enchaîne comme s’il « s’écrivait lui-même »
    • Forth est à la fois bootstrap, métaprogrammation, et peut devenir OS comme IDE/editor
    • cela mène à l’idée que si l’on construit l’interpréteur le plus simple possible pour une architecture CPU totalement nouvelle, on risque d’aboutir à quelque chose de proche de Forth

Petites implémentations de Forth et usages concrets

  • Forth peut définir davantage de Forth depuis Forth lui-même, et de nombreux Forth incluent aussi un assembleur
    • À la fin de JonesForth se trouve un stub d’assembleur fonctionnant dans Forth
    • ;CODE met à jour le header pour que le codeword pointe vers du code assemblé plutôt que vers DOCOL
  • PlanckForth est un Forth binaire écrit à la main de moins de 1 Ko
    • Un binaire ELF complet et une implémentation Forth fonctionnelle tiennent en moins de 1 Ko
    • bootstrap.fs part d’opérateurs ésotériques du début pour devenir, quelques centaines de lignes plus loin, un Forth lisible
  • Ces petites implémentations montrent la compressibilité extrême de Forth
    • SmithForth est un Forth en code machine écrit à la main par David Smith, présenté comme un système Forth de 1 000 octets et 1 000 lignes
    • sectorforth est un Forth de boot sector de 512 octets
  • Forth a été utilisé dans des centrales électriques, la robotique, des systèmes de suivi de missiles, l’automatisation industrielle, des langages embarqués pour jeux vidéo, des bases de données, la comptabilité, des traitements de texte, le graphisme, des systèmes de calcul, le boot loader Open Firmware, ainsi que sur divers processeurs et microcontrôleurs
  • Open Firmware est un cas important issu de l’ingénierie de Sun Microsystems
    • Sa base de langage de programmation interactif permet de tester efficacement de nouveaux matériels et d’en assurer le bring-up
    • Dans le cas de la navette spatiale ESN, Open Firmware est présenté comme un outil capable de déboguer le matériel, le logiciel, les pilotes plugins et même le firmware lui-même
  • Jupiter Ace était un ordinateur domestique britannique de 1982 dont le système d’exploitation était Forth
    • L’OS et la bibliothèque de routines tenaient dans une ROM de 8 Ko
    • Une citation de 1982 affirme que le Forth intégré était « 10 fois plus rapide » qu’un BASIC interprété, tout en demandant moins de la moitié de la mémoire
  • Le Canon Cat utilisait en 1987 un système d’exploitation Forth, qui faisait tenir l’OS, une suite bureautique et un environnement de programmation dans 256 Ko de ROM
    • C’était un produit matérialisant en matériel et logiciel l’interface centrée sur le clavier et la philosophie de conception de Jef Raskin
    • La procédure pour entrer dans l’interface Forth ne semble pas faire partie du flux d’usage prioritaire, mais quand on la connaît, quelques frappes suffisent

Logiciel spatial et Forth

  • L’un des usages les plus intéressants de Forth est l’exploration spatiale
    • Les engins spatiaux coûtent cher et sont difficiles, voire impossibles, à réparer, ce qui rend la fiabilité logicielle essentielle
    • La liste des projets de la NASA utilisant Forth est longue, et bien que le lien d’origine ait disparu, il en existe des copies sur Wayback Machine et forth.com
  • Le Space Shuttle Small Payload Accommodations Interface Module (SPAIM) est un exemple d’usage de Forth
    • L’équipe de développement écrivait des routines Forth sur PC, les téléchargeait, puis les testait de manière interactive
    • Une citation affirme que le logiciel de vol du SPAIM a fonctionné sans problème pendant la mission STS-45 de la navette
    • Le système Forth du SPAIM permettait le multitasking, chaque task ayant sa propre stack, avec une watchdog task surveillant l’état des stacks
  • Le Space Shuttle Robot Arm Simulator est un cas où un dispositif complexe a été développé par un seul programmeur en 5 semaines
    • Il devait accepter les commandes d’un joystick 3 axes pour piloter un bras de 50 pieds de long, doté de 6 articulations et de 6 systèmes de coordonnées
    • Une citation indique que le système comportait 14 process distincts
    • Une autre citation affirme que les tests de simulation étaient si rigoureux qu’après l’installation sur site, l’algorithme de contrôle exécutif n’a pas été modifié
  • Le Shuttle Mission Design and Operations System (SMDOS) était un logiciel de contrôle au sol du JPL
    • Pendant la mission SIR-B, plusieurs pannes matérielles ont été traitées sur place par des modifications logicielles
    • En raison de problèmes d’antenne et de changements d’orbite, une nouvelle stratégie de collecte de données était nécessaire, et SMDOS a servi à afficher des plans adaptés aux nouvelles conditions
    • Beaucoup de données ont été perdues, mais 20 % ont été récupérées via une méthode rotation-capture-rotation-transmission
  • Le Harris RTX2010 est un matériel Forth utilisé dans de nombreuses applications spatiales
    • Exécution directe de Forth
    • Deux hardware stacks d’une profondeur de 256 words
    • Horloge à 8 MHz et faible latence
    • Caractéristiques durcies aux radiations
  • Rosetta et Philae sont présentées comme la première mission à envoyer un vaisseau en orbite autour d’une comète puis à déposer un atterrisseur sur sa surface
    • L’Ion and Electron Sensor de Rosetta utilisait un Harris RTX2010
    • L’atterrisseur Philae utilisait deux RTX2010 dans le CDMS et deux pour le contrôle ADS
    • Rosetta a voyagé de 2004 à 2014 avant de rejoindre 67P/Churyumov-Gerasimenko
    • 67P mesure 4 km de large et orbite autour du Soleil tous les six ans et demi
  • Philae a subi des rebonds en faible gravité à la surface après l’échec de ses harpons et de son thruster d’atterrissage, mais s’est montré assez robuste pour accomplir « 80 % » de sa mission scientifique
  • Le cas d’un patch du code du magnétomètre de Galileo en 1993 est aussi évoqué
    • Le magnétomètre disposait d’un RCA1802, de 2 Ko de RAM et de 2 Ko de ROM, et était programmé en Forth sur un système de développement basé sur Apple II
    • Un mauvais octet mémoire est apparu au milieu du code de l’instrument, et il a fallu produire un patch pour ne pas utiliser cet octet
    • La personne citée explique avoir écrit de zéro, en Lisp, un environnement de développement Forth pour cet instrument et un simulateur matériel afin de générer le patch, en moins de trois mois à temps partiel

Forth est plus proche d’une idée et d’une filiation que d’une implémentation unique

  • Forth se rapproche davantage d’une idée dotée de concepts partagés et d’une filiation que d’une unique implémentation de référence
  • L’une des raisons pour lesquelles Forth est difficile à apprendre est qu’il n’existe pas d’implémentation unique représentant exclusivement le nom « Forth »
    • Certaines premières variantes de Forth sont antérieures au nom même de « Forth »
    • Le standard Forth se prolonge dans les documents ANS Forth, avec mention du standard Forth 2012 et du comité Forth200x
  • Les différents Forth partagent des concepts et des words communs, mais les Forth spécialisés pour un usage donné ont leur propre vocabulaire spécifique
  • Chuck Moore a fondé Forth, Inc en 1973, a depuis porté Forth sur de nombreux systèmes et continue de créer de nouveaux systèmes
  • colorForth est l’environnement tardif de Chuck Moore
    • La couleur du code source y remplace une partie de la ponctuation du Forth standard pour déterminer le mode de traitement des words
    • Il est expliqué que les couleurs simplifient la sémantique de Forth, accélèrent la compilation et aident aussi Moore malgré sa mauvaise vue
    • colorForth inclut son propre système d’exploitation de 63 Ko
  • Moore estime que les logiciels deviennent complexes à force d’ajouts successifs, au point que plus personne n’ose les modifier par crainte de conséquences imprévues
    • Cela mène à l’idée qu’il faut un programmeur dédié, prêt à consacrer sa carrière à une seule application pour la réécrire encore et encore jusqu’à la perfection

Affinité avec la machine, puces Forth, GreenArrays

  • Chuck Moore s’oppose à la complexité logicielle depuis les années 1950, et des citations le montrent considérant des systèmes d’exploitation comme Windows, UNIX et DOS comme incompréhensibles ou inutiles
  • L’auteur décrit la philosophie de Moore par Mechanical Sympathy
    • L’expression vient d’une citation du pilote de Formula One Jackie Stewart, et dans le contexte logiciel elle est utilisée dans Why Mechanical Sympathy? de Martin Thompson
    • Forth tend à être populaire auprès des « gens du hardware », comme les ingénieurs électriciens et les concepteurs de systèmes embarqués
  • La véritable passion de Chuck Moore semble être la conception de processeurs
    • Les Harris RTX2000 et RTX2010 sont présentés comme étant essentiellement des puces de Moore
    • Moore conçoit du hardware depuis le gate array Novix N400 de 1983, et une version améliorée du design a été vendue à Harris pour devenir les puces RTX
  • Moore a conçu des processeurs avec son propre logiciel VLSI OKAD, écrit en 500 lignes de Forth
    • VLSI Design Tools (OKAD) explique que 500 lignes de colorForth fournissent tout le nécessaire à la conception de puces
    • OKAD est une suite d’outils comprenant la technologie des portes logiques, le layout des circuits, la simulation du comportement électrique et l’export GDSII
  • Le Novix NC4000 est un moteur de traitement ultra-rapide conçu pour exécuter directement des instructions Forth de haut niveau
    • Il gagne en performances en supprimant l’assembly language classique et le microcode interne
    • Son architecture à double pile réduit fortement l’overhead d’implémentation des subroutines
  • Les puces GreenArrays sont présentées autour de l’intervention de Moore en 2013, « Programming a 144-computer chip to minimize power »
    • Une seule puce contient 144 ordinateurs asynchrones
    • Un core inactif consomme 100 nW, un core actif 4 mW, s’exécute à 666 Mips puis revient à l’état inactif
    • Quand tous les ordinateurs fonctionnent à vitesse maximale, la consommation atteint 550 mW, soit environ 0,5 W
  • Le document sur l’architecture GreenArrays met l’accent sur « NO CLOCKS »
    • Il explique que la génération et la distribution de l’horloge dans les ordinateurs classiques consomment beaucoup d’énergie même en attente, sans rien faire
    • GreenArrays est présenté non comme un Multi-Core CPU, mais comme un Multi-Computer System

Simplicité, efficacité et avenir du low-power computing

  • L’auteur estime que software et hardware ont continué à empiler toujours plus de couches de complexité
    • Le calcul dans les grands data centers est perçu comme bon marché ou gratuit, parce qu’il est indirectement payé par les budgets publicitaires
    • Ce qui est réellement payé, explique-t-il, c’est l’attention des utilisateurs et leurs données personnelles
  • Il soutient qu’il n’y a aucune raison de continuer à utiliser des logiciels toujours plus inefficaces et bâclés, avec des exigences matérielles de plus en plus fortes
  • Les langages proches de Forth pourraient avoir un avenir solide dans les domaines suivants
    • les petits ordinateurs omniprésents
    • l’alimentation solaire
    • les VM fortement contraintes
  • Le Dennard scaling s’est presque arrêté vers 2006
    • La relation selon laquelle des transistors plus petits permettaient des vitesses plus élevées et des tensions plus faibles a plafonné autour de 4 GHz à cause des fuites de courant et de la chaleur
    • The Free Lunch Is Over de Herb Sutter traite du basculement des gains de performance CPU vers le hyper-threading et le multicore
  • Pour Sutter, il faut soit repenser les applications pour la concurrence, soit écrire du code plus efficace et moins gaspilleur
    • Il dit que l’optimisation des performances ne va pas devenir moins importante, mais plus importante encore
  • Aujourd’hui, on peut acheter pour quelques pièces de monnaie des microcontrollers bien plus puissants que l’IBM 704, et écrire dessus un puissant system Forth
    • Les microcontrollers peuvent fonctionner avec une pile bouton ou un petit panneau solaire
    • Le texte poursuit en affirmant qu’il n’y a jamais eu de meilleure époque pour le petit computing
  • Pour comprendre Forth, il faut considérer la différence entre « simple » et « easy »
    • Simple Made Easy de Rich Hickey est présenté comme l’exposé qui a permis d’exprimer cette distinction
    • Forth n’est pas facile et n’est pas toujours agréable, mais c’est assurément un langage simple
  • Growing a Language de Guy Steele est une présentation montrant comment un langage se construit à partir de primitives
    • On peut aussi appliquer à Forth une citation sur Lisp : quand les nouveaux mots définis par l’utilisateur ressemblent à des primitives, et que les primitives ressemblent à des mots définis par l’utilisateur, on obtient un langage plus vaste sans couture
  • La recommandation finale est de créer le langage de programmation parfait pour soi-même

1 commentaires

 
GN⁺ 2023-07-18
Avis sur Hacker News
  • Dès que j’ai découvert Forth, je me suis dit qu’il fallait que j’en crée un moi-même, et j’ai donc fait MiniForth il y a deux ans en une semaine
    Je visais la Blue Pill et l’Arduino d’origine, mais je l’ai développé comme un compilateur croisé afin de pouvoir le tester sur l’hôte
    J’étais tellement absorbé que j’attendais avec impatience chaque soir après le travail pour bricoler dessus ; j’ai terminé en cinq soirées de semaine et un week-end, et créer un Forth était aussi amusant que cela
    Je recommande vivement cette expérience ; la seule autre fois où j’ai eu une révélation comparable, c’était lors de ma première rencontre avec les macros Lisp (https://www.thanassis.space/score4.html#lisp)
    • Exact. En première année, dans un cours d’architecture des ordinateurs, je devais faire un projet final à sujet libre pour le LC-3 ; comme j’avais déjà un peu touché à Forth avec le mod Minecraft RedPower 2, je me suis dit que ce serait amusant d’en implémenter un
      Cela a englouti presque tout mon temps libre du semestre, et un jour je n’ai réalisé que j’avais passé la nuit blanche qu’en voyant le soleil commencer à se lever et en regardant l’heure
      Je n’ai jamais utilisé Forth de manière pratique dans la vraie vie, mais l’expérience d’en construire un à partir de zéro se décrit presque justement comme une expérience religieuse
      C’était comme une distillation pure de ce que Fred Brooks disait de la programmation : le programmeur, comme le poète, travaille à peine éloigné de la matière brute de la pensée pure, bâtit des châteaux en l’air par la seule imagination, et un programme est une magie réelle où, si l’on saisit correctement l’incantation, quelque chose qui n’existait pas auparavant prend vie à l’écran
    • Tout à fait d’accord. Il y a très longtemps, j’ai écrit un compilateur Forth en ZX81 BASIC
      Afficher 1 000 nombres à l’écran, ce qui prenait 19 secondes, est devenu instantané
      J’en ai aussi tiré une grande leçon : en regardant le code machine généré, je pensais qu’il était parfait et impossible à améliorer, puis je suis revenu le lendemain et je l’ai rendu beaucoup plus rapide
  • On peut se demander : « Comment ça, il s’écrit lui-même ? Ça veut juste dire qu’on peut écrire des fonctions, non ? »
    C’est vrai dans une certaine mesure, mais Forth va plus loin dans le sens où l’on peut définir de nouveaux mots et les intégrer comme des parties du langage lui-même
    Ces mots peuvent être utilisés comme des opérations intégrées, et peuvent même modifier le fonctionnement du langage
    Comme c’est un langage extensible, on peut définir de nouvelles structures de contrôle ou créer des mots qui changent la syntaxe ; une telle flexibilité est rare dans d’autres langages
    En ce sens, Forth peut être vu comme un langage qui « s’écrit lui-même », car il permet au programmeur de personnaliser et d’étendre le langage à un niveau très fondamental
    C’est aussi comparable au système de macros de Lisp : de même que les macros Lisp permettent, via des transformations à la compilation, de créer de nouvelles constructions syntaxiques et des langages spécifiques à un domaine, les mots de Forth permettent d’étendre la syntaxe et les fonctionnalités
    • C’est cool, mais en presque 40 ans de carrière comme programmeur professionnel, le problème n’a jamais été la syntaxe, mais toujours la sémantique
      Il existe sans doute des cas, comme la multiplication de matrices, où écrire A = B + C * D; est préférable au fait d’énumérer chaque fonction à appeler, mais je n’ai jamais rencontré ce genre de problème en pratique
      Je me demande si c’est moi qui manque d’imagination, si c’est utile seulement dans certains domaines où je n’ai jamais travaillé, si la syntaxe de Forth est tellement pauvre qu’il faut l’étendre pour qu’elle devienne utilisable, ou si les gens veulent personnaliser leur langage comme d’autres tunent leur voiture
      Je ne comprends pas vraiment pourquoi les gens s’y intéressent autant
  • L’un des projets Forth les plus intéressants actuellement est Dusk OS, un système d’exploitation 32 bits écrit en Forth, avec son propre compilateur C, et plusieurs portages sont en cours
    https://duskos.org/
    • Je ne connais pas bien DuskOS lui-même, mais historiquement, même s’il est vrai que Forth était « son propre système d’exploitation », c’était assez rudimentaire comparé à ce qu’un lecteur moderne imaginerait comme un système d’exploitation
      Certes, il faut se demander ce qu’on peut attendre de quelque chose qui tourne même avec 8 Ko de RAM, mais s’il fournissait des fonctions primitives, il n’y avait historiquement presque pas de pilotes ni la plupart des concepts d’abstraction
      Le code était chargé depuis le source, donc lent ; l’édition de liens ressemblait surtout au chargement de blocs dans le bon ordre ; et pour charger un nouveau programme, il fallait d’abord retirer le programme courant
      Difficile de dire que c’était nettement mieux que CP/M, qui faisait souvent un démarrage à froid de la machine à la fin d’un programme, mais au moins CP/M séparait le BIOS et le BDOS
    • J’étais passé à côté de ça. Je venais de lire « Beyond the Collapse » et je me disais qu’avec mes compétences en Lisp, APL/J ou C, il serait difficile d’approcher la simplicité de Forth au niveau système d’exploitation
      Je compte vraiment regarder ça avant le week-end prochain
  • Mes premiers langages de programmation ont été l’assembleur x86 et Forth. Mon père était passionné par Forth, et c’est lui qui m’a appris à programmer
    Adolescent, j’ai créé plusieurs systèmes Forth x86 pour DOS, jusqu’à finir par « Third », une implémentation compatible ANS assez aboutie : https://github.com/benhoyt/third
    C’est assez étonnant de pouvoir avoir un compilateur Forth entièrement bootstrapé, assembleur inclus, en quelques milliers de lignes de code
    Il y a quelque temps, j’ai retranscrit un vieil article que j’avais coécrit pour le magazine Forth Dimensions
    Les idées de Forth restent bonnes, mais la manipulation de pile devient vite fastidieuse et très difficile à lire
    On le voit dans les exemples de code de https://benhoyt.com/writings/forth-lookup-tables/, en particulier Search-Table. Nommer les choses est difficile, mais ne pas les nommer semble encore plus difficile
    • Si la manipulation de pile devient fastidieuse, c’est peut-être parce que vous et moi ne sommes pas Chuck Moore
      Son code comporte en général très peu de brassage de pile. Exemple : http://www.merlintec.com/download/color.html
    • J’ai jeté un coup d’œil rapide au code source de Third, c’est intéressant
      Lors du bootstrap, il appelle kernel.com ; je me demande comment kernel.com a été construit
  • Conférence connexe de Chuck Moore : « Programming a 144 Computer Chip to Minimize Power » (2013)

https://www.youtube.com/watch?v=0PclgBd6_Zs
Voici, paraît-il, comment Forth fait tourner des ordinateurs à très basse consommation : GreenArrays livre une puce asynchrone à 144 cœurs, qui ne consomme que 7 pJ/inst
Les cœurs inactifs ne consomment pas d’énergie (100 nW), tandis que les cœurs actifs s’exécutent rapidement à 4 mW (666 Mips), puis repassent en veille en attendant une communication

  • « J’ai toujours pensé que la taille et la vitesse n’avaient d’importance que pour les amateurs. Mais dans le contexte moderne, il n’y a que trois paramètres qui comptent : la consommation, la consommation, la consommation »
    --Chuck Moore
    https://youtu.be/0PclgBd6_Zs?t=389
  • Je me demande sincèrement si ce genre d’architecture à phases ne va pas revenir dans les prochaines années
  • Un excellent ouvrage d’introduction est Starting Forth
    Il contient les illustrations les plus charmantes que j’aie vues dans un manuel
    [0] https://www.forth.com/starting-forth/
  • Il y a longtemps, quand OS/2 est sorti, un ami m’a rapporté que « les programmes OS/2 ne peuvent pas être écrits en assembleur, il faut les écrire en C »
    Par réaction, j’ai créé Forth/2
    C’était un compilateur Forth en code natif pour OS/2, à threading direct, écrit en assembleur ; Brian Matthewson a rédigé un excellent manuel, et il a eu quelques dizaines d’utilisateurs
    [1] https://sourceforge.net/projects/forth2/
  • Dans un registre un peu différent, je me souviens avoir lu la version prototype de la présentation originale de cet article
    Elle était fondamentalement identique au texte actuel, mais avec beaucoup moins de texte et davantage de blancs
    Je le mentionne parce que ce support illustre aussi la beauté du minimalisme côté technologie de site web sous-jacente
    [0] http://ratfactor.com/forth/forth_talk_2023.html
    [1] http://ratfactor.com/minslides/
  • Il est intéressant de voir qu’il existe aussi un compilateur Forth en Rust. Les ressources associées sont en [1]
    Son utilisation reste encore un peu obscure [2], mais il a déjà été mentionné ici auparavant [3], et l’implémentation semble solide
    Ce n’est pas une machine virtuelle Forth avec REPL, mais c’est une implémentation de machine virtuelle impressionnante
    Si FORTH est une machine virtuelle, j’ai toujours pensé que, lorsqu’on a besoin d’un petit système efficace capable de gérer des données en streaming, il pourrait être le meilleur choix pour obtenir des performances proches du bare metal
    Il y a aussi le fait qu’on n’a pas à se battre avec un système d’exploitation
    J’ai l’impression que c’est, en substance, ce que fait un FPGA, mais sur un CPU standard
    Je l’imagine toutefois comme un système spécialisé où il ne serait pas nécessaire d’écrire soi-même tous les pilotes pour se connecter au matériel requis
    [1] https://docs.rs/rust-forth-compiler/latest/src/rust_forth_co...
    [2] https://docs.rs/fortraith/latest/fortraith/
    [3] https://news.ycombinator.com/item?id=23501474
  • J’ai aussi implémenté un autre Forth moi-même
    Le but n’était pas de copier fidèlement l’idée originale, et il fonctionne un peu différemment
    Puisque l’article disait qu’on pouvait découvrir Forth, je laisse aussi mon implémentation ici : https://github.com/loscoala/goforth
    La plus grande différence est que, dans cette variante de Forth, le texte source est entièrement transformé en bytecode, et qu’il n’y a pas de runtime au sens classique de Forth
    Il est donc facile de traduire le bytecode en C
    J’utilise ce Forth pour générer du code C, puis j’intègre ce code dans d’autres logiciels
    • Cette approche peut être très productive et astucieuse, mais il faut garder à l’esprit que ce type de solution polyglotte peut facilement devenir un casse-tête de maintenance à long terme
      Il existe un très bon projet open source pour s’entraîner à l’oreille et à la lecture à vue, mais il est écrit dans un langage créé par son auteur, qui se compile en JavaScript
      La configuration de la chaîne d’outils est tellement pénible que, même en connaissant pas mal de bugs, je n’ai pas eu le courage de les corriger
      https://sightreading.training/
      https://github.com/leafo/sightreading.training
      Ce projet est écrit dans un langage appelé « Moonscript » : https://github.com/leafo/moonscript
      Moonscript se compile en Lua, et Lua se compile en JS
      C’est de la folie. Une folie géniale, certes, mais cela m’a quand même empêché de devenir contributeur