0. Finir l'exercice 9 du TD numéro 1. Étudier le corrigé du TD numéro 1. 1. En cours, nous avons vu une façon avec Emacs de mettre la région autour d'une fonction Lisp. C'était : M-C-a C-SPC M-C-e On soupçonne qu'il existe une fonction Emacs pour faire cela. Trouver cette fonction dans la documentation sur Emacs. Expliquer votre démarche. 2. Regarder le chapitre de la HyperSpec concernant `loop'. S'en servir pour : * Écrire une expression pour créer une liste des entiers entre 10 et 100 multiples de 7. * Numéroter les éléments d'une liste : (a b a c) => ((a . 0) (b . 1) (a . 2) (c . 3)) * Calculer l'age de la plus vieille personne d'une liste. 3. Écrire une macro `for-each-person' permettant d'écrire du code de type : (for-each-person (when (> age 44) (print size))) Utiliser la fonction `macroexpand-1' pour vérifier votre code. Réécrire les fonctions de l'exercice 10 du TD numéro 1 avec cette macro. 4. Voici un programme de différentiation symbolique simple utilisant la programmation dirigée par les données : (defparameter *differentiators* (make-hash-table :test #'eq)) (defun diff (var exp) (cond ((eq var exp) 1) ((or (symbolp exp) (numberp exp)) 0) (t (apply (gethash (car exp) *differentiators*) var (cdr exp))))) (setf (gethash '+ *differentiators*) (lambda (var x y) `(+ ,(diff var x) ,(diff var y)))) (setf (gethash '- *differentiators*) (lambda (var x y) `(- ,(diff var x) ,(diff var y)))) (setf (gethash '* *differentiators*) (lambda (var x y) `(+ (* ,(diff var x) ,y) (* ,x ,(diff var y))))) Tester le programme sur un certain nombre d'expressions. Identifier des duplications de code et du `bruit', à savoir du code sans importance pour l'application en question. Écrire une macro `def-diff' pour définir une fonction de différentiation permettant d'écrire quelque chose comme : (def-diff (- x y) `(- ,(diff var x) ,(diff var y))) Réécrire le code ci-dessus en utilisant la macro. Comparer la taille et la lisibilité du code sans et avec la macro. 5. Améliorer la macro de l'exercice 4 pour que l'on puisse écrire quelque chose comme ceci : (def-diff (- x y) `(- ,(@ x) ,(@ y))) Il suffit pour cela de définir `@' comme une macro. 6. Améliorer la macro de l'exercice 5 de manière à ce que `@' soit une macro locale à la macro def-diff (regarder pour cela `macrolet' de la HyperSpec). 7. Améliorer la macro pour que l'on puisse écrire quelque chose comme ceci : (def-diff (* x y) => (+ (* (@ x) y) (* x (@ y)))) [cette amélioration est un peu difficile].