Common Lisp exporting symbols from packages

前端 未结 4 2072
甜味超标
甜味超标 2021-02-13 05:40

Is there a short way of exporting all the symbols from a package or is it the only way to do it in defpackage. I generally write my code in a file foo.lisp

4条回答
  •  孤城傲影
    2021-02-13 06:16

    Vsevolod's post inspired me to post a macro as well:

    (defmacro defpackage! (package &body options)
      (let* ((classes (mapcan 
                        (lambda (x) 
                          (when (eq (car x) :export-from-classes)
                            (cdr x)))
                        options))
             (class-objs (mapcar #'closer-common-lisp:find-class classes))
             (class-slots (mapcan #'closer-mop:class-slots class-objs))
             (slot-names (mapcar #'closer-mop:slot-definition-name class-slots))
             (slots-with-accessors
               (remove-duplicates (remove-if-not #'fboundp slot-names))))
        (setf options (mapcar
                        (lambda (option)
                          (if (eq (car option) :export)
                            (append option 
                                    (mapcar #'symbol-name slots-with-accessors))
                            option))
                        options))
        (setf options (remove-if 
                        (lambda (option)
                          (eq (car option) :export-from-classes))
                        options))
        `(defpackage ,package ,@options)))
    

    To use:

    CL-USER> 
    (defclass test-class ()
      ((amethod :accessor amethod :initarg :amethod :initform 0)
       (bmethod :reader bmethod :initform 1)))
    #
    CL-USER> 
    (closer-mop:ensure-finalized  (find-class 'test-class))
    #
    CL-USER> 
    (macroexpand-1 
      `(defpackage! test-package
         (:export "symbol1")
         (:export-from-classes test-class)))
    (DEFPACKAGE TEST-PACKAGE
      (:EXPORT "symbol1" "AMETHOD" "BMETHOD"))
    T
    CL-USER> 
    

    This isn't well tested, and I'm still learning the MOP API, so there may be much better/cleaner ways to achieve the same goal here (especially the fboundp kludge). Also, this only looks for accessor functions on a class. There are also methods that specialize on a class. You could use the MOP to find those as well...

提交回复
热议问题