[Openmcl-devel] Defstruct inside eval-when strangeness and a build failure

Gary Byers gb at clozure.com
Tue Dec 29 22:20:48 PST 2009

On Mon, 28 Dec 2009, Stas Boukarev wrote:

> Compiling and loading the following results in "Undefined function FOO"
> (defun foo (&rest args)
>  (print "HELLO!"))
> (eval-when (:compile-toplevel :load-toplevel :execute)
>  (defstruct (test (:print-function foo))))
> (foo)

This behaves the same way when the DEFSTRUCT isn't enclosed in an
EVAL-WHEN, as far as I can tell.

DEFSTRUCT expands into code which calls FMAKUNBOUND on the symbols
that name the predicate/copier/constructor/etc. functions that it
generates.  This makes at least some sense in most cases (or once
seemed to), in that it makes it easier to redefine those functions.

Ordinarily, you get a CERROR if you try to redefine most functions
that're defined in the implementation; if you really, really want to
do that without getting the CERROR, you can do something like:

? (fmakunbound 'cdr) ; one could argue that a CERROR should happen here, too
? (defun cdr (x) (aref x 0))
;;; Wackiness ensues ...

I think that the rationale for that was likely some combination of
"well, if you're going to that much trouble to redefine CDR .." and
"hmm.  There needs to be -some- way to do that ..."

Regardless of what one thinks of using FMAKUNBOUND to remove redefinition
protection, there's at least some motivation for having DEFSTRUCT use this
mechanism to allow redefinition of automatically generated functions (though
you should probably be discouraged from casually redefining a predefined
structure ...).

A named PRINT-FUNCTION isn't automatically generated, so even if you believe
that un-defining the constructor/copier/predicate/etc before redefining them
is somehow justified, it's harder to see a good reason to FMAKUNBOUND a
user-defined print function.

It's probably more common to define structure print functions after the
structure's defined (to the extent that PRINT-FUNCTIONs are still used, rather
than PRINT-OBJECT methods), but it's not a requirement and DEFSTRUCT can't
assume that and clearly shouldn't call FMAKUNBOUND on the name of a print
function.  (Unless there's another reason for it that I'm not remembering,
un-defining the automatically generated functions seems at least somewhat
suspect as well.)

> And also a minor problem: this change
> http://trac.clozure.com/ccl/changeset/13337/trunk/source/lisp-kernel/pad.s
> prevents from building ccl.

Fixed yesterday; thanks.

> -- 
> With Best Regards, Stas.
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list