(gile) Posté(e) le 18 mai 2014 Partager Posté(e) le 18 mai 2014 Salut, Un sujet récent m'a donné envie de mettre en oeuvre un processus proche de ce qu'on appelle en anglais precomputation.L'implémentation de ce mécanisme en AutoLISP à été décrit dans TheSwamp par Michael Puckket (MP) ici et là. Il s'agit donc, dans un soucis de performances, de n'effectuer certaines opérations qu'au premier appel d'une fonction et d'utiliser les résultats de ces opérations aux appels suivants, ces résultats étant enregistrés dans la fonction. Prenons un exemple simple. Chargez et exécutez la fonction ci-dessous.Elle vous demande votre nom et affiche une boite d'alerte pour vous dire personnellement bonjour. Rien de bien extraordinaire jusque là, mais si vous rappelez HELLO, la boite d'alerte s'affichera en spécifant votre nom mais sans vous l'avoir redemandé. (defun c:hello () (eval (list 'defun 'c:hello '() (list 'alert (strcat "\nBonjour " (getstring "\nVotre nom: ")) ) '(princ) ) ) (c:hello) ) Ceci est possible en LISP parce qu'un programme LISP est une liste et qu'un programme LISP peut construire et évaluer une liste. Examinons le code ci-dessus. À l'intérieur d'une définition de fonction classique, on trouve deux expressions :un appel à eval auquel est passé une construction de liste en argument.un appel à la fonction elle même. Toute la magie réside dans la construction de cette liste. Certains éléments sont "quotés" et ne seront pas évalués par la fonction list d'autres ne le sont pas et seront donc évalués lors de la construction de cette liste. Si on évalue l'expression suivante dans la Console de l'éditeur ou en ligne de commande :(list 'defun 'c:hello '() (list 'alert (strcat "\nBonjour " (getstring "\nVotre nom: ")) ) '(princ) )On est invité à entrer son nom (ici : "Toto") et on obtient :(DEFUN C:HELLO nil (ALERT "\nBonjour Toto") (PRINC))Ici, seule l'expression :(strcat "\nBonjour " (getstring "\nVotre nom: ")) a été évaluée. En évaluant cette liste avec eval, la fonction c:hello se redéfinit elle même avec le nom entré par l'utilisateur "en dur", puis s'appelle elle même pour afficher la boite d'alerte :(defun c:hello (/ s) (DEFUN C:HELLO nil (ALERT "\nBonjour Toto") (PRINC)) (c:hello) ) On peut, bien sûr, utiliser ce processus pour des fonctions plus utiles. Par exemple, lire un fichier texte pour récupérer toutes les lignes dans une liste qui devrait être utilisée par une autre fonction qui peut être appelée plusieurs fois. (defun readLines (/ filename) (eval (list 'defun 'readLines '() (if (setq filename (getfiled "Choisir le fichier" "" "*" 0)) (list 'quote ((lambda (/ sel file line ind lst) (setq file (open filename "r")) (while (setq line (read-line file)) (setq lst (cons line lst)) ) (close file) lst ) ) ) '() ) ) ) (readLines) )Au premier appel de (readLines), l'utilisateur est invité à spécifier un fichier, celui-ci est lu et une liste contenant toutes les lignes du fichier est créée. aux appels suivants (readLines) la liste, stocké "en dur" dans la fonction, sera directement retournée. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 19 mai 2014 Partager Posté(e) le 19 mai 2014 après avoir vu l'application pour la traduction, je comprend mieux l’intérêt...merci de nous faire profiter de tes recherche et de tes lumières... même si dans mon cas c'est un peu de utopique de penser à une mise en application... quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
GEGEMATIC Posté(e) le 19 mai 2014 Partager Posté(e) le 19 mai 2014 Salut,le mécanisme est vraiment astucieux, d'une subtilité bien lispienne ...par contre je me pose la question de l'avantage par rapport à un code plus balourd avecune variable globale, du genre :(if (not GC-Ton-Nom) (setq GC-ton-Nom (getstring "Ton nom ?")))dans ton cas, tu vas économiser le if not, mais tu vas compliquer la mise en place d'une option de relecture dont l'utilisateur peut avoir besoin. Maintenant il y a peut être un avantage d'occupation mémoire lors de la lecture de fichiers volumineux: !c:hello#<SUBR @0000000034e5cae8 C:HELLO> le résultat est compilé,alors que ma variable globale sera une liste. Je m'interroge, mais c'est sympa de nous l'avoir fait découvrir ...Gérald ----------------------------------------------------------------------Site: https://www.g-eaux.frBlog: http://g-eaux.over-blog.com Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 19 mai 2014 Auteur Partager Posté(e) le 19 mai 2014 Salut Gérard, Je ne pense pas qu'il y ait de réelle différence en terme de performances avec l'utilisation d'une variable globale. C'est juste pour montrer un moyen d'éviter de se servir de variables globales en utilisant une voie plus typée "programmation fonctionnelle", et puis, pour "aller plus loin en LISP". Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
Patrick_35 Posté(e) le 20 mai 2014 Partager Posté(e) le 20 mai 2014 Salut Intéressante l'astuce. Je pense comme Gérald qu'avec une variable, cela ne change pas grand-chose, mais la démarche est intelligente. Merci @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824 Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant