[Openmcl-devel] defstruct - generic constructor?

Paul Krueger plkrueger at comcast.net
Wed Apr 29 15:07:19 PDT 2009


David,

If you can control the structs you use so that you always use the  
default constructor and want something generic that works for an  
arbitrary structure type, why not define a macro to do it for you:

(defmacro make-struct-instance (struct-type &rest slot-val-pairs)
     `(funcall (symbol-function (find-symbol (concatenate 'string   
"MAKE-" (string-upcase (string ,struct-type)))))
               , at slot-val-pairs))

Now you can have a variable number of keyword args and do things like:

?  (make-struct-instance 'thing :s1 3 :s2 'a)
#S(THING :S1 3 :S2 A)
? (setf typ 'thing)
THING
? (make-struct-instance typ :s2 15)
#S(THING :S1 NIL :S2 15)
?

This makes some assumptions about the case of the structure name that  
you might want to modify. And to be resilient you'd want to make sure  
that the resulting "MAKE-..." symbol actually exists and is bound to a  
function before funcalling it, but you get the idea.

For more details on structures in general check out chapter 19 of  
"Common Lisp, the Language" which you can find online at:
http://www.cs.cmu.edu/Groups/AI/html/cltl/cltl2.html

On Apr 29, 2009, at 4:00 PM, David Reitter wrote:

> Sorry, I should have made clear that I need a _generic_ constructor,
> that is, a constructor for a type specified dynamically.  (The `chunk-
> type' variable in my example.)
>
> On Apr 29, 2009, at 4:56 PM, Laughing Water wrote:
>
>> Fortunately, the even more obvious solution works!
>>
>> Whenever you use defstruct, you're also getting a constructor. For
>> example,
>>
>> (defstruct probe time temperature)
>>
>> (setf *my-probe* (make-probe))
>>
>> Others more advanced than me will give a more complete answer.
>>
>> Laughing Water
>>
>>
>> On Apr 29, 2009, at 2:26 PM, 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?
>>>
>>> Thanks for your input.
>>> _______________________________________________
>>> Openmcl-devel mailing list
>>> Openmcl-devel at clozure.com
>>> http://clozure.com/mailman/listinfo/openmcl-devel
>>
>>
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel




More information about the Openmcl-devel mailing list