Given that I have a structure defined with a set of fields, how do I
iterate down all the fields of the structure given an instance of the
structure?
I could do away with the structure and use simple lists, but then I
will have to manage the accessors as well.
I could of course specify that the struct be stored as a list, but if
I do so is it safe to apply ordinary lisp iterators to the structure?
I am a bit hesitant to do this because it means taking advantage of
the fact that the structure has been implemented as a list.
Is there a nice way of iterating down all the fields of a structure
without resorting to such hacks?
Thanks,
--Raman
--
T. V. Raman <·····@cs.cornell.edu>Tel: (607)255-7421 R 272-2435
Office: 5162 Upson Hall,
Department of Computer Science, Cornell University Ithaca NY 14853-6201
Res: 226 Bryant Avenue Ithaca NY 14850
In article <·····················@cs.cornell.edu> ·····@cs.cornell.edu (T. V. Raman) writes:
>Given that I have a structure defined with a set of fields, how do I
>iterate down all the fields of the structure given an instance of the
>structure?
(defstruct struct
slot1 slot2 slot3 ...)
(defconstant *structure-slot-accessors*
(list #'struct-slot1 #'struct-slot2 #'struct-slot3 ...))
(defun map-struct-slots (function struct)
(dolist (accessor *structure-slot-accessors*)
(funcall function (funcall accessor struct))))
There's no portable way to generate the list of accessors, nor access
structure slots without using the accessors. The FAQ posting contains some
implementation-specific information about accessing slots, though.
>I could of course specify that the struct be stored as a list, but if
>I do so is it safe to apply ordinary lisp iterators to the structure?
Of course; it's still just a list. DEFSTRUCT is merely being used to
define accessor functions for clarity.
>I am a bit hesitant to do this because it means taking advantage of
>the fact that the structure has been implemented as a list.
But that's the whole reason for using the :TYPE option! If you didn't want
to take advantage of the representation, you wouldn't specify it.
--
Barry Margolin
System Manager, Thinking Machines Corp.
······@think.com {uunet,harvard}!think!barmar
In article <······················@informatik.uni-hamburg.de>, ··@ki2.informatik.uni-hamburg.de writes:
|> In article <············@early-bird.think.com> ······@think.com (Barry Margolin) writes:
|> > There's no portable way to generate the list of accessors, nor access
|> > structure slots without using the accessors.
|>
|> The idea is to define... a defstruct macro that
|> expands to the "old" defstruct from Common Lisp plus some additional code
|> that is responsible for storing structure information into a data structure
Every Common Lisp implementation itself must cache this structure slot information (e.g., for use with the #S reader macro). IMO, the quickest and most painless way to solve the original poster's problem is to define a function that gets the slots names by calling the implementation-dependent slot-retrieval function(s). Example (untested):
(defun structure-slot-accessors (struct)
(mapcar #'symbol-function
#+lucid (loop with type = (sys:structure-type struct)
for slot-index in (sys:structure-info type)
collect (second (multiple-value-list
(sys:defstruct-slot-info
type slot-index))))
#-lucid (error "Teach me how to find the slot names of ~a."
struct)
))
(defun map-slots (fn struct)
(loop for accessor in (structure-slot-accessor struct)
collect (funcall fn (funcall accessor struct))))
..................................................
Len Charest, Jr.
JPL Artificial Intelligence Group
·······@aig.jpl.nasa.gov