When STRUCTURE-OBJECTs (and some other types of objects) appear as literal, constant objects in code being processed by COMPILE-FILE, COMPILE-FILE needs to know how to arrange that, when the resulting binary file is loaded, an "equivalent" object is created. There are many possible definitions of "equivalent" : sometimes, it's important that components of the loaded object share structure with other objects, sometimes it's important that initialization happens in a certain way, and sometimes none of these things are important. To determine how to recreate the constant object, COMPILE-FILE calls the generic function MAKE-LOAD-FORM; this behavior should be described in any CL reference or tutorial. (A reference or tutorial should also note that the implementation can't define default MAKE-LOAD-FORM methods that would be applicable to all instances of STRUCTURE-CLASS or STANDARD-CLASS, and should also note that MAKE-LOAD-FORM-SAVING-SLOTS is a convenient function to use in MAKE-LOAD-FORM methods for objects whose initialization doesn't need to be complicated, e.g.:
(defmethod make-load-form ((p point) &optional env)
(declare (ignore env))
(make-load-form-saving-slots p))
Note that that method has to be defined at compile-time, so that COMPILE-FILE can call it to determine how to save the constant POINT object.
None of this is CCL-specific. What might be is the question of which things are constant, literal objects and which things aren't.
In code like:
(defconstant a-point (make-point :x 0 :y 0 :z 200))
(defun return-a-point () a-point)
the compiler's allowed (but not required) to substitute the value of A-POINT for the reference to it in the function RETURN-A-POINT. (If the compiler does so, that would
mean that there's a literal/constant POINT object in the code being compiled, and COMPILE-FILE would need to call MAKE-LOAD-FORM to determine how the object should be saved and loaded; if the compiler doesn't do this substitution, then MAKE-LOAD-FORM doesn't need to be called in this example.)
Whether an implementation does this kind of substitution or not is up to the implementation. The spec also leaves it unspecified as to whether the value form in a DEFCONSTANT form is evaluated at compile-time, load-time, or both, and notes that care must be exercised (by the user) to ensure that the expression always evaluates to the same value.
CCL generally tries to evaluate the DEFCONSTANT value form at compile-time, and is fairly aggressive about substituting the values of named constants for references to them; in some cases, this means that MAKE-LOAD-FORM methods on the classes of the constants' values must be defined. Other implementations may be less willing to do this substitution for some types of objects. Both strategies are correct, and portable code can't assume which strategies are being followed (though much purportedly portable code surely does make such assumptions.)
Different treatment of things defined by DEFCONSTANT seems like the mostly likely cause of this sort of thing (unexpected calls to MAKE-LOAD-FORM which no one's bothered to define). One can avoid some of these issues in a way that should be portable by doing:
(defconstant a-point (make-point :x 0 :y 0 :z 200))
(defun return-a-point () (load-time-value (symbol-value 'a-point)))
This will have a similar effect to simply allowing an implementation that wants to do so (as CCL does) to do constant-substitution, but the use of LOAD-TIME-VALUE will ensure that the constant value is evaluated only at load time (and that MAKE-LOAD-FORM won't be involved.)
RETURN-A-POINT
in yourDEFCONSTANT
form? – Brundage