Il est facile de comprendre que le langage de programmation du future si ce n'est déjà le cas aujourd'hui, sera du pseudo code traité par l'IA. Et qu'est ce que le pseudo-code si ce n'est un code écrit dans un langage sur demande.... D'où l'importance de pouvoir choisir son langage de programmation. Ne dit-on pas que la moitier de la résolution d'un problème est résolue par sa formalisation dans un langage sur mesure ?
Les algèbres multi-sortes sont la base des interpréteurs multilangages. Néanmoins les expressions avec nom d'opérateur, parenthèse et virgule peuvent vite devenir illlisibles de par un trop grand nombre de parenthèses emboitées. Pour rendre le langage plus lisible pour un humain, on autorise des syntaxes alternatives, préfixe, infixe, postfixe et délimité, qui nous permettent de définir un véritable langage de programmation mutable. Et on autorise des patrons, des macros, qui permettent de sous-entendre la plus grande partie de l'expression.
Les langages de programmation comme les langages scientifiques et mathématiques possèdent tous la propriété d'être facilement reconnaissable. Cela vient du fait que l'on souhaite condenser dans une formule un ensemble de connaissances à transmettre, et donc dont le but par principe est d'être facile à lire. Or qu'est ce que cela vaut dire "facilement reconnaissable" ? Que l'on repaire immédiatement l'éventuelle erreur de syntaxe.
Partant de ce principe on s'intéresse qu'aux seuls langages dont la syntaxe est résolue par un automate, en une seule lecture de l'expression. Cela va imposer un certain nombre de contraintes sur la conception du langage, et l'on ne pourra pas implémenter toutes les syntaxes altérnatives évoquées précédement en même temps ou sans autre contrainte.
La programmation assistée par l'IA, nous permet de mettre facilement en oeuvre les constructions d'algèbre multi-sorte ainsi que toutes sortes d'algorithmes applicables à ces structures. Cela modifit l'ordre des pertinences dans les constructions (et même des conceptions mathématiques). On s'attardera dans le choix d'une nomenclature de structures et d'une formalisation des opérations sur ces structures. Cela révèlera un nouvel attrait pour le constructivisme par le bas.
On discute avec l'IA sur les langages d'opérateurs et les automates reconnaissant ces langages. Puis on étend progressivement en plusieurs langages imbriqués avec leur automates les reconnaissant. Puis on étend les langages pour pouvoir programmer les automates eux-mêmes, et pour finalement proposer un interpréteur multilangage modifiable à volonté.
Le procédé pouvant prétendre à une certaine universalité, il sera rechercher une terminologie consensuelle (basée sur une norme hispano-latine telle que proposée par la communauté "Désanglisation de la programmation"), des mots-clefs qui donnent envie d'être utilisés.
Comme nous somme soucieux de rendre moins ingrate ces recherches pour ne pas décourager les néophytes, nous proposerons à chaque étape des résultats intermédiaires sous forme d'outils concrets.
La première étape consiste en la conception d'un interpréteur d'algèbre multi-sorte, capable de reconnaitre un terme, capable d'énumérer tous les termes possibles, capable de générer un terme au hasard.
La construction ayant quelque prétention à l'universalité, l'ordre des constructions et des concepts à définir revête une grande importance. Le premier prompt est celui définissant une algèbre libre engendrée par des opérateurs internes.
On définit un langage algébrique, et plus précisément un langage associé à une algèbre libre, en présentant ses éléments générateurs et ses opérateurs générateurs entre crochet <...>. Chaque opérateur possède une arité indiquée occasionnellement par le suffixe (.) pour unaire, (.,.) pour binaire, (.,.,.) pour ternaire. Exemple :
L = <a, b, f(.), g(.,.), h(.,.,.,.)>
Il convient de proposer à l'utilisateur les outils les plus démonstratifs avec les arguments par défaut necéssaires pour cela. Puis il est préférable de regouper ces informations concernant une structure dans la structure elle-même. C'est pourquoi on perfectionne tout de suite la définition du langage avec la possibilité d'ajouter des information concernant chaque symbole, et on commence par des poids associés à chaque générateur. Cela est nécessaire lorsque l'on veut générer au hasard un terme, ou attribuer aux termes une taille pondérée.
On ajoute un poids à chaque générateur. Le suffixe :p fixe le poids, positif, nul autorisé, 1 par défaut. Exemple :
L = <a:9, b, f(.):3, g(.,.), h(.,.,.,.)>
Notre vision étant par essence récursive, on oriente notre IA dans cette vision d'un traitrement récurcif pour reconnaitre un terme du langage.
On définit un automate récursif qui reconnaît les termes du langage <a, b, f(.), g(.,.), h(.,.,.,.)>. L'automate est représenté par un ensemble de règles de production : {|--a, |--b, |--f(.), |--g(.,.), |--h(.,.,.,.)}
Chaque élément de cet ensemble est une règle de production possible. Le symbole point désigne un terme quelconque du langage, et constitue un appel récursif de cet automate.
Sans développer davantage la conception du langage, on peut demander à l'IA de programmer une fonction idioma("<a,b,f(.), g(.,.),h(.,.,.)>") qui retourne l'automate capable de reconnaitre un élément du langage. Un petit synopsis à destination de l'utilisateur devra être consultable par la commande.
Programme en python une fonction idioma("<a,b,f(.), g(.,.),h(.,.,.,.)>") qui retourne cet automate capable de reconnaître un terme du langage.
Et fait une synopsis à destination de l'utilisateur qui devra être accessible par la commande synop(idioma).
L'algèbre comprend un ensemble de règles de production, un ensemble d'éléments générateurs, un ensemble d'opérateurs générateurs, une liste de symboles générateurs (regroupant opérateurs générateur et éléments générateurs mais énuméré dans un ordre), et une méthode pour reconnaitre un terme.
A = idioma("<a:9,b,f(.):3, g(.,.)>") Construit l'automate `A`Attributs : A.regles = {'|--g(.,.)', '|--b', '|--a', '|--f(.)'} Régles de productionA.generateurs = {'a':9, 'b':1} Eléments générateursA.operateurs = {'f':(1,3), 'g':(2,1)} Opérateurs générateursA.symboles = [('a', 0, 9), ('b', 0, 1), ('f', 1, 3), ('g', 2, 1)] Symboles générateursMéthodes : A.reconnait("g(f(a),b)") = vero Teste si le terme appartient au langage.A.reconnait("g(f(b))") = falso
On peut penser que ces 4 attributs et cette méthode sont des identifiants suffisament généraux pour devoir leur attribuer des noms commun de programmation (mot-clef).
Voyons ce que ChatGPT peut nous proposer concernant le nom de méthode "reconnait" :
On définie un langage algébrique, et plus précisément un langage associé à une algèbre libre, par la liste de ses éléments générateurs et opérateurs générateurs entre crochets "<a,b,f(.),g(.,.)>". La fonction "idioma" appliqué à la chaine "<a,b,f(.),g(.,.)>" retourne l'automate capable de reconnaitre un terme du langage algébrique en question.
Le nom "idioma" obéit bien à la norme hispano-latine.
L'automate possède une méthode, "reconnait", qui appliqué à une chaine retourne vrai si c'est un terme du langage et faux sinon. Quel mot-clef de norme hispano-latine pourrait remplacer le nom de méthode "reconnait" ?Dans ce cas précis, je choisirais acepta. La distinction conceptuelle est utile :
- un automate reconnaît un langage ;
- un automate accepte ou rejette une chaîne particulière.
Ainsi :
</> Python
L = idioma("<a,b,f(.),g(.,.)>")L.acepta("a") # vero
L.acepta("f(a)") # vero
L.acepta("g(a,b)") # vero
L.acepta("g(a)") # falsoacepta présente plusieurs avantages : c'est espagnol, très court, issu du latin acceptare, et son sens correspond exactement à l'usage classique en théorie des automates.
reconoce serait néanmoins également très bon, et c'est la traduction hispanique directe de reconnait :
L.reconoce("f(a)")Mais je réserverais idéalement reconoce à une relation plus générale avec le langage :
« El autómata reconoce el idioma L. »
« El autómata acepta el término t. »Une troisième possibilité serait pertenece, qui exprime directement l'appartenance :
L.pertenece("f(a)")Cela se lit comme :
f(a) pertenece a L.Mais grammaticalement, c'est plutôt le terme qui appartient au langage, et non le langage qui « pertenece » au terme. En notation objet, L.pertenece(t) est donc légèrement moins naturel.
Je proposerais donc la norme suivante :
Donc, pour votre bibliothèque, idioma(...).acepta(terme) me paraît être la formulation la plus précise et la plus élégante.
Opération Mot-clef recommandé Construire le langage / automate idioma(...) Tester si une chaîne est un terme accepté acepta(...) Dire qu'un automate reconnaît un langage reconoce(...) Valeurs retournées vero / falso
On part d'un langage L que l'on définit par l'instruction L = idioma("<a,b,f(.),g(.,.)>"). C'est le langage d'une algèbre libre. Le langage comprend une méthode d'exécution ejec. L'éxecution d'un terme du langage, son interprétation, s'apparente à un morphisme de sructure. On introduit un nouveau préfixe pour indiquer la substitution à faire dans la chaine de caractère d'un appel de fonction par son résultat. En l'absence d'implémentation, il existe une implémentation par défaut qui ne perd aucune information et qui correspond presque à l'identité :
On résume cela par les expressions :
a = ( |->a)
f = ( x|->f(ejec(x)) )
g = ( (x,y)|->g(ejec(x), ejec(y)) )
On utilise le langage pour piloter un système. D'un point de vue informatique et mathématique, un élément générateur désigne une procédure sans argument qui s'exécutera dans le système piloté et retournera un élément de la structure image, un élément qui dépend donc de l'état du système piloté. Un opérateur générateur désigne une procédure de même arité prenant comme argument des éléments de la structure image, et s'exécutera dans le système piloté pour retourner un élément de la structure image, mais la procédure peut interagire avec des paramètres propre à l'état du système piloté. L'évauation du terme est la valeur retourné lors de l'exécution du terme, sachant que l'exécution du terme ne va pas eulement retourné son évaluation mais peut modifier des paramètres d'état supplémentaire (effet de bord). On est donc ammené à considérer les éléments et opérateurs exangues de ces paramètres, et donc indépendant de l'état modifiable du sytème piloté. On les qualifie de pure. Certains éléments et opérateurs dépendent de paramètres du système piloté, et ont comme action de modifer d'autres paramètres de ce même système. On peut définir les effets de bords d'un symbole par ses deux ensembles, l'ensemble `A` des paramètres dont il dépend, et l'ensemble `B` des paramètres qu'il est susceptibles de modifier. Le symbole est isolé si et seulement si nous avons à la fois, son ensemble `A` disjoint des ensembles `B` de tous les symboles, et son ensemble `B` disjoint des ensembles `A` de tous les symboles. La relation de dépendance se définit comme suit : Un symbole `X` dépend du symbole `Y` si et seulement si `X"."A nn Y"."B ≠ 0`. Autrement dit, le symbole `X` dépend du symbole `Y` si et seulement si l'exécution de `X` avant celle de `Y` (avec la même évaluation paramétrique) est suceptible de changer le résulta attendu de l'exécution de `Y`.
On raccorde l'implémentation en associant chaque symbole à une procédure de même arité. L'instruction L.implemanta([A,B,F,G]) va modifier l'implémentation du langage comme suit : le symbole 'a' sera associé à la procédure nullaire A, le symbole 'b' sera associé à la procédure nullaire B, le symbole 'f' sera associé à la procédure unaire F, et le symbole 'g' sera associé à la procédure binaire G. Et par exemple : L.ejec("g(f(a),b)") exécutera l'instruction G(F(A()),B()) et retournera son résultat qui devra être une chaine de caractères. Cette méthode ejec constitue l'interpréteur. C'est l'opération de base d'un interpréteur appelée « traduction mot-à-mot » appliqué ici à une simple algèbre libre.
Les langages évolués sont encore des langages algébriques, et donc obéïssent aux règles précédentes. Et il est tout à fait pertinant, utile, et politiquement non-neutre, à un moment où il est justement important de prendre position, de vouloir établir une norme sur les principes généraux de programmation, sachant que les anciens langages ne seront peut ou plus utilisés dans la phase de conception des programmes.
Répondre sur Communauté Reddit