Une boucle de lecture-évaluation-impression ( REPL ), également appelée shell de niveau supérieur interactif ou shell de langage , est un environnement de programmation informatique interactif simple qui prend des entrées utilisateur uniques, les exécute et renvoie le résultat à l'utilisateur ; un programme écrit dans un environnement REPL est exécuté par morceaux. Le terme fait généralement référence à des interfaces de programmation similaires à l'environnement interactif classique de la machine Lisp . Les exemples courants incluent les shells de ligne de commande et les environnements similaires pour les langages de programmation , et la technique est très caractéristique des langages de script .
Histoire
En 1964, l'expression cycle READ-EVAL-PRINT est utilisée par L. Peter Deutsch et Edmund Berkeley pour une implémentation de Lisp sur le PDP-1 . Un mois plus tard, Project Mac publie un rapport de Joseph Weizenbaum (le créateur d' ELIZA , le premier chatbot au monde) décrivant un langage basé sur REPL, appelé OPL-1, implémenté dans son langage Fortran-SLIP sur le Compatible Time Sharing System (CTSS) .
Le manuel de référence Maclisp de 1974 de David A. Moon atteste de la « boucle de lecture-évaluation-impression » à la page 89, mais n'utilise pas l'acronyme REPL.
Depuis au moins les années 1980, les abréviations REP Loop et REPL sont attestées dans le contexte de Scheme .
Aperçu
Dans une boucle REPL, l'utilisateur entre une ou plusieurs expressions (plutôt qu'une unité de compilation entière ) et la boucle REPL les évalue et affiche les résultats. Le nom de boucle read–eval–print vient des noms des fonctions primitives Lisp qui implémentent cette fonctionnalité :
- La fonction read accepte une expression de l'utilisateur et l' analyse dans une structure de données en mémoire. Par exemple, l'utilisateur peut saisir l' expression s
(+ 1 2 3), qui est analysée dans une liste chaînée contenant quatre éléments de données. - La fonction eval prend cette structure de données interne et l'évalue. En Lisp, évaluer une expression s commençant par le nom d'une fonction signifie appeler cette fonction sur les arguments qui composent le reste de l'expression. La fonction
+est donc appelée sur les arguments1 2 3, ce qui donne le résultat6. - La fonction print prend le résultat généré par eval et l'affiche à l'utilisateur. S'il s'agit d'une expression complexe, elle peut être imprimée de manière plus esthétique pour la rendre plus facile à comprendre.
L'environnement de développement revient ensuite à l'état de lecture, créant une boucle qui se termine lorsque le programme est fermé.
Les REPL facilitent la programmation exploratoire et le débogage car le programmeur peut inspecter le résultat imprimé avant de décider quelle expression fournir pour la lecture suivante. La boucle lecture-évaluation-impression implique le programmeur plus fréquemment que le cycle classique édition-compilation-exécution-débogage.
Étant donné que la fonction print génère le même format textuel que celui utilisé par la fonction read pour l'entrée, la plupart des résultats sont imprimés sous une forme qui peut être copiée et collée dans le REPL. Cependant, il est parfois nécessaire d'imprimer des représentations d'éléments qui ne peuvent pas être relus de manière sensée, comme un handle de socket ou une instance de classe complexe. Dans ces cas, il doit exister une syntaxe pour les objets illisibles. En Python, c'est la <__module__.class instance>notation, et en Common Lisp, la #<whatever>forme. Le REPL de CLIM , SLIME et la Symbolics
Lisp Machine peut également relire des objets illisibles. Ils enregistrent pour chaque sortie quel objet a été imprimé. Plus tard, lorsque le code est relu, l'objet sera récupéré à partir de la sortie imprimée.
Les REPL peuvent être créés pour prendre en charge n'importe quel langage textuel. La prise en charge des REPL pour les langages compilés est généralement obtenue en implémentant un interpréteur sur une machine virtuelle qui fournit une interface au compilateur. Par exemple, à partir de JDK 9, Java a inclus JShell comme interface de ligne de commande pour le langage. Divers autres langages disposent d'outils tiers disponibles en téléchargement qui offrent une interaction shell similaire avec le langage.
Utilisations
En tant que shell , un environnement REPL permet aux utilisateurs d'accéder aux fonctionnalités pertinentes d'un système d'exploitation en plus de fournir un accès aux capacités de programmation. L'utilisation la plus courante des REPL en dehors des shells de systèmes d'exploitation est le prototypage interactif . D'autres utilisations incluent le calcul mathématique, la création de documents intégrant l'analyse scientifique (par exemple IPython ), la maintenance interactive de logiciels, l'analyse comparative et l'exploration d'algorithmes.
Spécificités de Lisp
Mise en œuvre
Une définition minimale est :
( définir ( REPL env ) ( imprimer ( eval env ( lire ))) ( REPL env ) )
où envreprésente evall'environnement initial -uation. On suppose également que envpeut être mis à jour de manière destructive par eval.
Fonctionnalité
Les fonctionnalités typiques fournies par un REPL Lisp incluent :
- Historique des entrées et des sorties.
- Des variables sont définies pour les expressions d'entrée et les résultats. Ces variables sont également disponibles dans REPL. Par exemple, dans Common Lisp,
*elles font référence au dernier résultat**et***aux résultats qui le précèdent. - Niveaux des REPL. Dans de nombreux systèmes Lisp, si une erreur survient pendant la lecture, l'évaluation ou l'impression d'une expression, le système n'est pas renvoyé au niveau supérieur avec un message d'erreur. Au lieu de cela, un nouveau REPL, un niveau plus bas, est démarré dans le contexte d'erreur. L'utilisateur peut alors inspecter le problème, le corriger et continuer – si possible. Si une erreur survient dans un tel REPL de débogage, un autre REPL, à nouveau un niveau plus bas, est démarré. Souvent, le REPL propose des commandes de débogage spéciales.
- Gestion des erreurs . Le REPL fournit des redémarrages. Ces redémarrages peuvent être utilisés, lorsqu'une erreur survient, pour revenir à un certain niveau REPL.
- Entrée et sortie d'objets de données sensibles à la souris .
- Édition d'entrée et complétion spécifique au contexte sur les symboles, les noms de chemin, les noms de classe et d'autres objets.
- Aide et documentation pour les commandes.
- Variables permettant de contrôler le lecteur. Par exemple, la variable *read-base* contrôle dans quelle base les nombres sont lus par défaut.
- Variables permettant de contrôler l'imprimante. Exemple : longueur maximale ou profondeur maximale des expressions à imprimer.
- Syntaxe de commande supplémentaire. Certains REPL ont des commandes qui ne suivent pas la syntaxe s-expression, mais fonctionnent souvent avec des données Lisp comme arguments.
- REPL graphiques. Certains REPL Lisp (le CLIM Listener en est un exemple) acceptent également les entrées et sorties graphiques.