[Openmcl-devel] defstruct - generic constructor?

Robert Goldman rpgoldman at sift.info
Wed Apr 29 14:53:01 PDT 2009


David Reitter wrote:
> I've been trying to make instances of objects whose types have been  
> defined using `defstruct'.
> 
> Unfortunately, the obvious `make-instance' doesn't work (with ccl at  
> least).  I'm glad, however, that `class-of' and `class-name' do their  
> jobs.
> 
> The only way I got this to work was this clumsy hack:
> 
> (apply (read-from-string (format nil "make-~a" (class-name chunk-type)))
> ...)
> 
> Is there a nicer, more efficient way of doing this?
> I'd need to find out what the constructor is for a given class.   
> Reading the `defstruct'  code didn't help me much.
> 
> In more general terms, can I expect that `class-of' and `class-name'  
> work for structures in other CL implementations?

Actually, your hack above won't reliably work.  There's no guarantee
that the constructor for a class will have the make-<class-name> name.
This is a default behavior, but it can be overridden.

The hyperspec:

"defstruct defines a constructor function that is used to create
instances of the structure created by defstruct. The default name is
make-structure-name. A different name can be supplied by giving the name
as the argument to the constructor option. nil indicates that no
constructor function will be created."

Also, if there's a boa constructor, it's possible that calling the
constructor with no arguments won't work.

Question:  are all of the structures that you might want to make under
your control?  If so, this isn't a problem.  You can ensure that the
default constructor is always available, and your hack will work.

As an aside, it seems likely that (intern <name> <package>) will be more
efficient than read-from-string, and it won't be busted by changes to
*package* in the surrounding environment.

Best,
r



More information about the Openmcl-devel mailing list