Any tips on saving a macro / function call?

Some time ago, for a small example based on zoo, I wrote the base class ANIMAL, some subcategories of CAT, MOUSE, etc. a generic FEED method using the ANIMAL parameter and some methods specialized for each ANIMAL subtype.

After writing the second and third classes, a couple of methods, I realized that I was repeating the same thing many times and decided to write the DEF-ANIMAL-SUBCLASS macro, which was extended in PROGN, which defined a new subclass and the corresponding method.

Then I realized that I had just given my users the ability to define their own ANIMAL subtypes, which they might find useful! However, although they can simply do this in a running image, I had no way to save the new ANIMAL type so that if the image was restarted, the new ANIMAL type would be re-created for them (without having to re-evaluate the macro).

Is there a common way to do this?

Shouldn't this be done?

Any hints would be greatly appreciated!

Greetings

R

+3
source share
3 answers

If you define animal classes using a macro, you can let the macro write the source code.

Example (works in LispWorks):

, , , , alist. .

(defclass animal ()
  ((source :allocation :class :initform nil)))

, .

(defmacro def-animal-class (&whole code name feeding )
  `(progn
     (defclass ,name (animal) ())
     (defmethod feed ((animal ,name)) ,@feeding)
     (let ((item (assoc ',name
                        (slot-value (class-prototype (find-class 'animal))
                                    'source))))
       (if item
           (setf (cdr item) ',code)
         (setf (slot-value (class-prototype (find-class 'animal))
                           'source)
               (list (cons ',name ',code)))))
     ',name))

?

CL-USER > (pprint (macroexpand-1 '(def-animal-class cat ((print "feeding a cat")))))

(PROGN
  (DEFCLASS CAT (ANIMAL) NIL)
  (DEFMETHOD FEED ((ANIMAL CAT)) (PRINT "feeding a cat"))
  (LET ((ITEM (ASSOC 'CAT (SLOT-VALUE (CLASS-PROTOTYPE (FIND-CLASS 'ANIMAL))
                                      'SOURCE))))
    (IF ITEM
        (SETF (CDR ITEM) '(DEF-ANIMAL-CLASS CAT ((PRINT "feeding a cat"))))
      (SETF (SLOT-VALUE (CLASS-PROTOTYPE (FIND-CLASS 'ANIMAL)) 'SOURCE)
            (LIST (CONS 'CAT '(DEF-ANIMAL-CLASS CAT ((PRINT "feeding a cat"))))))))
  'CAT)

:

CL-USER 75 > (def-animal-class cat ((print "feeding a cat some more")))
CAT

CL-USER 76 > (cdr (first (slot-value (class-prototype (find-class 'animal))
                                     'source)))

(DEF-ANIMAL-CLASS CAT ((PRINT "feeding a cat some more")))

, , DEF-ANIMAL-CLASS. :

(with-open-file (s "~/animals.sexp" :direction :output :if-exists :supersede)
  (pprint (slot-value (class-prototype (find-class 'animal)) 'source) s))

READ .

+7

- . , CLSQL , .

, .

, , < <20 > def... .lisp. , . ( . , , ?) , Emacs .

+5

Lisp - , , , , Inaimathi, ( , , ..), .

, CL, . CCL ccl:save application, SBCL sb-ext:save-lisp-and-die, CLISP ext:saveinitmem ..

Which of these methods (one of the proposed Inaimathi or image preservation) of course depends on your application and needs, since each of them has different advantages and disadvantages.

+3
source

All Articles