From: Juliusz Chroboczek
Subject: Clarifications about MAKE-LOAD-FORM
Date: 
Message-ID: <7ill8v1jlx.fsf@lanthane.pps.jussieu.fr>
Is it portable to use MAKE-LOAD-FORM to dump the results of a
macroexpansion?  I'm too dense to understand 3.2.4.4.

I'm using something that does roughly

  (defstruct foo
    stuff
    )

  (defmethod make-load-form ((foo foo) &optional env)
    (declare (ignore env))
    (make-load-form-saving-slots foo))

  (defmacro define-foo (name &rest stuff)
    `(defparameter ,name ,(make-foo :stuff (mapcar #'eval stuff))))

except that the STUFF is the result of a lengthy computation that I
really want to happen at compile-time, not at load-time[1].  It
appears to work in both CMUCL and CLISP, but I'd like to know whether
I'll get in trouble with other implementations.

Another question: where do I find the set of built-in types that the
fasdumper is guaranteed to be able to dump?  I've found, to my great
dismay, that while CLISP can dump compiled functions, CMUCL cannot:

  (define-foo *foo* #'list)

  ...

  ; In: DEFINE-FOO *FOO*

  ;   (DEFINE-FOO *FOO* #'LIST)
  ; --> DEFPARAMETER PROGN SETQ SETQ #S(FOO :STUFF (#<Function LIST {1010A4E1}>)) 
  ; --> PROGN PROGN SETF PCL::SET-SLOT-VALUE PCL::ACCESSOR-SET-SLOT-VALUE LET 
  ; ==>
  ;   '(#<Function LIST {1010A4E1}>)
  ; Error: Cannot dump objects of type FUNCTION into fasl files.
  ; 

Thanks for your help,

                                        Juliusz

From: Bruno Haible
Subject: Re: Clarifications about MAKE-LOAD-FORM
Date: 
Message-ID: <d0q4rn$pim$1@laposte.ilog.fr>
Juliusz Chroboczek wrote:
> Is it portable to use MAKE-LOAD-FORM to dump the results of a
> macroexpansion?

Yes, if the result doesn't contain literal objects of "weird" type.

> I'm using something that does roughly
>
>  (defstruct foo
>    stuff
>    )
>
>  (defmethod make-load-form ((foo foo) &optional env)
>    (declare (ignore env))
>    (make-load-form-saving-slots foo))
>
>  (defmacro define-foo (name &rest stuff)
>    `(defparameter ,name ,(make-foo :stuff (mapcar #'eval stuff))))
>
> except that the STUFF is the result of a lengthy computation that I
> really want to happen at compile-time, not at load-time[1].  It
> appears to work in both CMUCL and CLISP, but I'd like to know whether
> I'll get in trouble with other implementations.

This is fairly common and portable use of MAKE-LOAD-FORM.

> Another question: where do I find the set of built-in types that the
> fasdumper is guaranteed to be able to dump?

You find it in section 3.2.4, which you already read :-).

> I've found, to my great dismay, that while CLISP can dump compiled
> functions, CMUCL cannot:
>
>  (define-foo *foo* #'list)
>  ; Error: Cannot dump objects of type FUNCTION into fasl files.

You can try to use a function of type FUNCALLABLE-STANDARD-OBJECT
instead, and define a MAKE-LOAD-FORM method for it:

(defclass named-function (funcallable-standard-object)
  ((name :initarg :name))
  (:metaclass funcallable-standard-class))

(defmethod shared-initialize :after ((fn named-function) situation &rest more)
  (when (or (eq situation 't) (member 'name situation :test #'eq))
    (set-funcallable-instance-function fn
                                       (fdefinition (slot-value fn 'name)))))

(defparameter *foo* (make-instance 'named-function :name 'list))

(funcall *foo* 'a 'b 'c) => (A B C)

(defmethod make-load-form ((fn named-function) &optional env)
  (make-load-form-saving-slots fn :slot-names '(name) :environment env))

            Bruno
From: Juliusz Chroboczek
Subject: Re: Clarifications about MAKE-LOAD-FORM
Date: 
Message-ID: <7iacpb1ff2.fsf@lanthane.pps.jussieu.fr>
> This is fairly common and portable use of MAKE-LOAD-FORM.

Cool.  Thanks.

>> Another question: where do I find the set of built-in types that the
>> fasdumper is guaranteed to be able to dump?

> You find it in section 3.2.4, which you already read :-).

Ah, I see.  (It's defined as the domain of a partial equivalence relation
-- Lisp humour?)

> You can try to use a function of type FUNCALLABLE-STANDARD-OBJECT
> instead, and define a MAKE-LOAD-FORM method for it:

Unfortunately, I cannot -- the function I'd like to dump is provided
by the user of DEFINE-FOO, and I cannot choose how it's built.

I guess the only solution is to have DEFINE-FOO record the actual
forms that were provided to it, and restrict it to be used in a null
lexical environment.  Does anyone see a better solution?

                                        Juliusz