• Aucun résultat trouvé

Le toplevel CLISPest muni d’un éditeur de ligne, similaire à un éditeur de commandes sous shell (ksh, bashoutcsh), avec des commandes à la Emacs.

Parmi les fonctionnalités précieuses,

– la complétion de symboles, par le caractèreTAB(→), permet de retrouver facilement les fonctions existantes ;

– on remonte aux expressions tapées précédemment avec la ↑ ouC-p, ou enfin avec une recherche en arrièreC-r;

L’éditeur de ligne de CLISP utilise la fonctionnalité readline de GNU : http://tiswww.case.edu/php/chet/readline/rluserman.html.

5.4

Fonctions de traçage

(TRACE fn1 ... fnn, n > 0) →

Trace les fonctions en argument — chaque appel d’une fonction tracée affiche un message à l’entrée et à la sortie de la fonction, avec les valeurs des paramètres et du retour. On peut aussi tracer certaines méthodes des fonctions génériques (pour les grands).

(UNTRACE fn1 ... fnn, n ≥ 0) →

Enlève la trace des fonctions en argument, de toutes les fonctions tracées s’il n’y a pas d’argument.

5.5

Le mode debug

Chaque exception ouvre une boucle d’inspection read-eval-printdans l’environnement de l’er- reur : c’est le mode debug. Si le code erroné est compilé, il n’y a rien à faire — si ce n’est charger le code interprété pour (essayer de) faire apparaître l’erreur. En mode interprété, on a accès aux valeurs de toutes les variables et on peut se déplacer dans la pile. En mode debug, le prompt est précédé du niveau de profondeur (chaque erreur l’incrémente de 1) : il ne faut pas rester en mode debug et il faut penser à en sortir.

Les commandes du mode debug sont des symboles réservés, tapés comme pour évaluer une variable, qui ne sont pas évalués (mais uniquement dans ce mode). Les principales sont :

– la commandehelpliste les commandes disponibles ; – abortpermet de sortir d’un niveau de debug ;

– C-d(contrôle-d) a un effet similaire àabort, sauf qu’il a un effet de reprise de l’évaluation dans certains cas (après un break ouC-cpar exemple) : en cas de boucle infinie, il est impératif de sortir parabort;

attention, trop deC-dfont sortir de l’environnement CLISP; – whereaffiche l’expression dans laquelle a eu lieu l’erreur ;

– uppermet de remonter jusqu’à l’endroit où on peut identifier le contexte et analyser la valeurs des variables de l’environnement courant ;

– downpermet de redescendre.

Le bon usage du mode debug consiste à rechercher la cause de l’erreur, en commençant parwhere puis en remontant (up) jusqu’à arriver au niveau où la cause est identifiable. A tout moment, les variables de l’environnement courant peuvent être inspectées. Lorsque l’erreur est identifiée, il faut sortir du mode debugparabortouC-d.

Le mode debug ne marche que pour du code interprété : lorsque l’erreur survient dans une fonction compilée, l’erreur est localisée à l’interface de l’interprété et du compilé, lorsque l’appelant est interprété et l’appelé compilé.

5.6

Fichiers de définitions

Bien qu’il soit possible de définir les fonctions au toplevel de l’interprète, il est plus commode de les définir dans des fichiers et de charger ces fichiers par la fonction suivante.

(LOAD file) → t

Charge le fichier de nomfile, c’est-à-dire exécute sur ce fichier une boucleREAD-EVALjusqu’à la fin du fichier.

D’un point de vue méthodologique, on évitera de mélanger des définitions et des exécutions : d’une part, la fonctionloadne fait pas deprintet ne permet pas de vérifier les exécutions, d’autre part il faut pouvoir charger les définitions sans entraîner des erreurs dues à des tests incorrects. Donc si vous voulez faire des tests dans un fichier, faites le dans un fichier séparé.

Editeurs de texte En CLISP, les fichiers de définition de fonctions ont par défaut l’extension ".lsp" ou ".lisp". Les “bons” éditeurs de texte (emacs,vim,eclipse) ont un mode LISP et reconnaissent ces extensions. Dans le mode LISP, ils mettent en valeur les «( )» et indentent automatiquement.

5.7 La compilation 61

Pouremacs, il peut être nécessaire d’activer la mise en valeur des parenthèses (menu “Options”, Paren Match Highlighting) et il faut alors sauvegarder les options (même menu, Save Options).

Des informations concernant SLIME, un mode pouremacsdédié à LISP, se trouvent à cette adresse : http://common-lisp.net/project/slime/.

Indentation En complément de la mise en valeur des parenthèses, il est indispensable de disposer de l’indentation automatique : c’est ce qui va permettre de reconnaître d’un seul coup d’œil, dans quelle expression est incluse une sous-expression. En général, l’indentation d’une ligne est automatique mais le passage à la ligne est manuel : s’inspirer des exemples de définition de fonctions dans les chapitres 2 et 3.

Sous emacs, l’indentation d’une ligne par rapport à la précédente s’obtient avec la touche tab (ou →). On peut indenter globalement une région (par exemple la définition d’une fonction ou la totalité d’un fichier) en sélectionnant cette région puis en faisantM-x indent-region. Enfin,M-x indent-sexp(ou C-M-q) indente à partir de la ligne courante.

Sousvim, mettreset autoindentdans le fichier.vimrc: le curseur se positionne automatiquement à chaque passage à la ligne.

5.7

La compilation

LISP est un langage interprété muni d’un compilateur. Deux fonctions permettent de compiler une fonction particulière, ou un fichier, c’est-à-dire toutes les fonctions d’un fichier. On ne compilera bien sûr que les fichiers de définitions, jamais les fichiers de tests. Voir aussi la section2.8.

(COMPILE fn) →

Compile la fonction de nomfn. (COMPILE-FILE file) →

Compile le fichier source de nomfilepour produire un fichier compilé : attention, il faut charger ensuite ce fichier par la fonctionloadpour pouvoir évaluer le code compilé.

Diverses options sont disponibles (cf. manuel [CLI97b]).

En CLISP, les fichiers de code compilé, produits par la fonction compile-file, ont l’extension ".fas".

Recueil d’exercices 63

6

Recueil d’exercices

Une bonne λ-abstraction vaut toujours mieux qu’un mauvais copier-coller.

Ce chapitre regroupe des problèmes (sans les solutions) qui ont été donnés en sujet d’examen ou de TD ces dernières années. Inutile de dire qu’ils constituent de bons exercices. De très nombreux autres exercices sont disponibles dans les nombreux manuels et sur le Web.

6.1

Fonctions de tri

On suppose donné un prédicat de comparaison, λ-expression à deux arguments, qui retourne nonnil ounilsuivant que le test de comparaison est vérifié ou pas.

Il s’agit de définir l’ensemble des fonctions de tri suivantes, en cherchant un compromis simplicité / efficacité. Si les algorithmes optimaux ne sont pas recherchés, il s’agit de se servir des propriétés des arguments, en particulier du fait qu’une liste est déjà ordonnée ou pas.

(BEST fn ll) → élément

Recherche dans la listellnon ordonnée le meilleur élément d’aprèsfn. (INSERT fn x ll) → liste

Insère dans la listelldéja ordonnée d’aprèsfnl’élémentx. (MERGE fn l1 l2) → liste

Fusionne les listesl1etl2déja ordonnées d’aprèsfn.

(SORT fn ll) → liste

Trie la listelld’aprèsfn.

Mis à part la première, ces trois fonctions peuvent se faire en modification physique (ninsert,nmergeet nsort) ou en partage (insert,mergeetsort).