• [^] # Re: Exemple de test d'un code retour erreur en Lisp ?

    Posté par . En réponse à la dépêche Peter Seibel : Practical Common Lisp. Évalué à 2.

    Oui, mais on pourrait s'en passer en utilisant des macros, qui sont vraiment vraiment différentes de celles utilisés en C. Exemple avec une macro reprise du livre « On Lisp »:
    CL-USER 12 > (defmacro aif (test-form then-form &optional else-form)
     `(let ((it ,test-form))
     (if it ,then-form ,else-form)))
    AIF
    CL-USER 13 > (defun ma-function ()
     120)
    MA-FUNCTION
    CL-USER 14 > (aif (ma-function)
     (print it)
     (print 'returned-value-is-nil))
    120 
    120
    CL-USER 15 > (defun ma-function ()
     nil)
    MA-FUNCTION
    CL-USER 16 > (aif (ma-function)
     (print it)
     (print 'returned-value-is-nil))
    RETURNED-VALUE-IS-NIL 
    RETURNED-VALUE-IS-NIL
    
    Pour comprendre ce qu'il se passe, regarder la transformation (qui a lieu avant l'évaluation) qui va affecter la variable IT en appelant « test-form » et exécuter soit « then-form », soit « else-form », en fonction de la valeur de IT.
    CL-USER 17 > (macroexpand-1 '(aif (ma-function)
     (print it)
     (print 'returned-value-is-nil)))
    (LET ((IT (MA-FUNCTION))) 
     (IF IT 
    	 (PRINT IT) 
    	 (PRINT (QUOTE RETURNED-VALUE-IS-NIL))))
    T
    
    C'est grâce aux macros que Lisp peut être qualifié de « programmable programming language »... Autre example pour planquer du code avec WITH-OPEN-FILE (qui fait partie du standard):
    (with-open-file (mon-flux "fichier" :direction :output)
     (write "Bonjour!" mon-flux)
     (write "Au revoir!" mon-flux))
    
    qui donnera:
    (LET ((#:INTERNAL-STREAM631 (OPEN "fichier" :DIRECTION :OUTPUT)) 
     (#:DELETE632 T))
     (UNWIND-PROTECT
     (MULTIPLE-VALUE-PROG1 (LET ((MON-FLUX #:INTERNAL-STREAM631))
     (WRITE "Bonjour!" MON-FLUX)
     (WRITE "Au revoir!" MON-FLUX))
     (SETQ #:DELETE632 NIL))
     (WHEN #:INTERNAL-STREAM631 
    	 (CLOSE #:INTERNAL-STREAM631 :ABORT #:DELETE632))))