Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Iterate over a struct slots

356 views
Skip to first unread message

Nicolas Edel

unread,
Nov 22, 2011, 10:25:36 AM11/22/11
to

(defstruct foo
(slot1)
(slot2)
(slot3))

(defvar i0 (make-foo ...))
(defvar i1 (make-foo ...))

Now Suppose I want to merge i1 into i0 using the following rule:
for each slot of i0
do
if slot is null
then
slot of i0 := slot of i1
end
end

Is there a way to iterate on a struct slots ?
I did it using a macro with slot names as parameters, but this looks
like hugly code. And I can't imagine I would have to duplicate code in
Lisp, so there should be a nice way.


:Nicolas

Pascal J. Bourguignon

unread,
Nov 22, 2011, 11:02:04 AM11/22/11
to
Nicolas Edel <nicola...@gmail.com> writes:

> (defstruct foo
> (slot1)
> (slot2)
> (slot3))
>
> (defvar i0 (make-foo ...))
> (defvar i1 (make-foo ...))
>
> Now Suppose I want to merge i1 into i0 using the following rule:
> for each slot of i0
> do
> if slot is null
> then
> slot of i0 := slot of i1
> end
> end
>
> Is there a way to iterate on a struct slots ?

Yes.


> I did it

So you already knew there was a way.


> using a macro with slot names as parameters, but this looks
> like ugly code. And I can't imagine I would have to duplicate code in
> Lisp, so there should be a nice way.

You have to do the book-keeping yourself. But there's no need to
duplicate code. You have enough abstration tools not to have to.


Did you want to do it only for FOO structures?

If not, did you consider inherited structures ("included" structures)?
A FOO is not necessary just a FOO...

If you want to do that a lot, consider using CLOS objects, for which
there is a MOP.

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

Carlos

unread,
Nov 22, 2011, 11:30:50 AM11/22/11
to
On Tue, 22 Nov 2011 07:25:36 -0800 (PST)
Nicolas Edel <nicola...@gmail.com> wrote:
> Now Suppose I want to merge i1 into i0 using the following rule:
> for each slot of i0
> do
> if slot is null
> then
> slot of i0 := slot of i1
> end
> end
>
> Is there a way to iterate on a struct slots ?

You can use :type in the defstruct and then iterate over the underlying
list or vector. I don't know if it's portable.
--

Nicolas Edel

unread,
Nov 22, 2011, 12:36:13 PM11/22/11
to
On Nov 22, 5:02 pm, "Pascal J. Bourguignon" <p...@informatimago.com>
wrote:
> Nicolas Edel <nicolas.e...@gmail.com> writes:
> > (defstruct foo
> >   (slot1)
> >   (slot2)
> >   (slot3))
>
> > (defvar i0 (make-foo ...))
> > (defvar i1 (make-foo ...))
>
> > Now Suppose I want to merge i1 into i0 using the following rule:
> > for each slot of i0
> > do
> >     if slot is null
> >     then
> >         slot of i0 := slot of i1
> >     end
> > end
>
> > Is there a way to iterate on a struct slots ?
>
> Yes.
>
> > I did it
>
> So you already knew there was a way.
>

Yes, but not using any generic scheme.
I did something like this:

(defun merge-foo (var0 var1)
(macrolet ((merge-slot (slot var0 var1)
(let ((slot-name (intern (concatenate 'string
"FOO-" (symbol-name slot)))))
`(when (null (,slot-name ,var0))
(setf (,slot-name ,var0) (,slot-
name ,var1)))))
(merge-slots (var0 var1)
`(progn
(merge-slot slot1 ,var0 ,var1)
(merge-slot slot2 ,var0 ,var1)
(merge-slot slot3 ,var0 ,var1))))
(merge-slots var0 var1)
var0))

> Did you want to do it only for FOO structures?

No: I have 3 different structures. The reason I'd like to avoid code
duplication.

> If not, did you consider inherited structures ("included" structures)?
> A FOO is not necessary just a FOO...

No, I didn't. But what else could be a FOO ?


:Nicolas

Pascal J. Bourguignon

unread,
Nov 22, 2011, 2:01:05 PM11/22/11
to

Nicolas Edel

unread,
Nov 22, 2011, 2:19:09 PM11/22/11
to
On Nov 22, 8:01 pm, "Pascal J. Bourguignon" <p...@informatimago.com>
wrote:
> [...]
> Have a look at:
>
> http://groups.google.com/groups/search?hl=en&as_q=define-structure&as...

Looks like I didn't use the right keywords for my search.
Thanks.

:Nicolas

Captain Obvious

unread,
Nov 23, 2011, 7:50:47 AM11/23/11
to
PJB> If you want to do that a lot, consider using CLOS objects, for which
PJB> there is a MOP.

Is there any reason to prefer structs over CLOS objects? (Aside from cases
when you want vector or list representation.)
I like how it automatically creates accessors and stuff, but CLOS support
seems to be more consistent.
For example, SBCL barfed after I redefined structure slots. Maybe that was
just a bug in a particular SBCL version, but structure redefinition isn't
guaranteed to work.
So this is kinda problematic during development when things can change, and
manual definitions of initargs and accessors seems to be a small price.

BTW is there some widespread alternative to defclass which would give
defstruct's niceties?

Nicolas Edel

unread,
Nov 23, 2011, 8:45:26 AM11/23/11
to
On Nov 23, 1:50 pm, "Captain Obvious" <udode...@users.sourceforge.net>
wrote:
>  PJB> If you want to do that a lot, consider using CLOS objects, for which
>  PJB> there is a MOP.
>
> Is there any reason to prefer structs over CLOS objects? (Aside from cases
> when you want vector or list representation.)
> I like how it automatically creates accessors and stuff, but CLOS support
> seems to be more consistent.

The fact you can (read (print instance)) with structures is sometimes
really valuable. I use this to share data across several lisp
processes (used as cgi scripts, with an external rw-lock to ensure
integrity).

:Nicolas

paul-d...@sbcglobal.net

unread,
Nov 23, 2011, 12:57:04 PM11/23/11
to
Is there any advantage to that over an appropriate PRINT-OBJECT method?

smh

unread,
Nov 23, 2011, 6:30:25 PM11/23/11
to
I haven't seen anyone mention that in some implementations class-slots
and slot-value and setf of slot-value will all work on a structure-
class and a structure-object, just like they do on standard-class and
standard-object. This isn't portable, obviously.

While many feel that there is little reason to use defstruct rather
than defclass, except in rate situations where the speed and
inlinability of structure accessors is an important advantage.

Nicolas Edel

unread,
Nov 24, 2011, 3:17:23 AM11/24/11
to
On Nov 23, 6:57 pm, paul-donne...@sbcglobal.net wrote:
It's already implemented *and* is readable ?

Tim Bradshaw

unread,
Nov 25, 2011, 2:56:15 AM11/25/11
to
On 2011-11-23 23:30:25 +0000, smh said:

> While many feel that there is little reason to use defstruct rather
> than defclass, except in rate situations where the speed and
> inlinability of structure accessors is an important advantage.

Even then, it might be more that structure slot access is reliably
good, while standard-class slot access is very variable depending on
all sorts of phases of celestial bodies - I remember, vaguely, testing
some implemenentation (which was probably Allegro but might have been
LW) where in some good cases, class slot access performed really
extraordinarily well (much better than I would have expected it was
possible to do).

Pascal Costanza

unread,
Nov 26, 2011, 8:47:26 AM11/26/11
to
On 23/11/2011 13:50, Captain Obvious wrote:
> PJB> If you want to do that a lot, consider using CLOS objects, for which
> PJB> there is a MOP.
>
> Is there any reason to prefer structs over CLOS objects? (Aside from
> cases when you want vector or list representation.)

Structs are usually more efficient by default, and are easier to
optimize further when necessary. For example, stack allocation of struct
instances is supported in some Common Lisp implementations, but I'm not
aware that that would be the case for CLOS instances as well.

Serializing structs (via print) is easier. Some time ago, we had some
problems with serializing CLOS instances, whereas serializing struct
instances was straightforward. I don't remember the details anymore, though.

> BTW is there some widespread alternative to defclass which would give
> defstruct's niceties?

I recall seeing some alternatives, but I don't think it's worth the
hassle. Just cook up your own macro, it's not hard.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
The views expressed are my own, and not those of my employer.

Sam Steingold

unread,
Nov 27, 2011, 2:30:28 PM11/27/11
to
> * smh <funs...@tznvy.pbz> [2011-11-23 15:30:25 -0800]:
>
> While many feel that there is little reason to use defstruct rather

(defstruct s a) is just 3 words, and I get so many goodies defined for me:
make-s, s-a, (setf s-a).
with defclass, I need to do much more typing.
think macros which expand to defstruct
(e.g., defcsv in clocc/cllib/csv.lisp)

> than defclass, except in rate situations where the speed and
> inlinability of structure accessors is an important advantage.

this too may be a big issue; sometimes speed trumps extensibility and features.

--
Sam Steingold (http://sds.podval.org/) on Ubuntu 11.10 (oneiric) X 11.0.11004000
http://iris.org.il http://honestreporting.com http://dhimmi.com
http://palestinefacts.org http://pmw.org.il http://camera.org http://ffii.org
In the race between idiot-proof software and idiots, the idiots are winning.

Sam Steingold

unread,
Nov 28, 2011, 6:28:56 PM11/28/11
to
> * Sam Steingold <f...@tah.bet> [2011-11-27 14:30:28 -0500]:
>
>> * smh <funs...@tznvy.pbz> [2011-11-23 15:30:25 -0800]:
>>
>> While many feel that there is little reason to use defstruct rather
>
> (defstruct s a) is just 3 words, and I get so many goodies defined for me:
> make-s, s-a, (setf s-a).

and, of course, a print-object method which prints readably, so that the
data can be written to a file!

> with defclass, I need to do much more typing.
> think macros which expand to defstruct
> (e.g., defcsv in clocc/cllib/csv.lisp)

--
Sam Steingold (http://sds.podval.org/) on Ubuntu 11.10 (oneiric) X 11.0.11004000
http://mideasttruth.com http://ffii.org http://pmw.org.il
http://iris.org.il http://honestreporting.com http://memri.org
If you know that you know nothing, you know too much.
0 new messages