From: Jeronimo Pellegrini
Subject: Are structures obsoleted by CLOS?
Date: 
Message-ID: <f70081$h8p$1@aioe.org>
Hi,

I have seen different kinds of advice on the use of structures and
classes. For example, Peter Seibel mentions in PCL (page 204) that:

"the macro DEFSTRUCT also defines new classes. But that's largely for
backward compatibility -- DEFSTRUCT predated CLOS and was retrofitted
do define classes when CLOS was integraded into the language."

However, the style guide from the ALU at
http://www.lisp.org/table/style.htm says:

"When you don't need the full power of CLOS, consider using structures
instead. They are often faster, take up less space, and easier to use."

CLtL2 also has, on section 19.2:
"The defstruct feature is intended to provide ``the most efficient''
structure class"

So... Are structures really obsoleted by CLOS, or are structures
actually more efficient in any way (speed, memory, whatever)?

Thanks,
J.

From: ··@codeartist.org
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <1184075090.883246.274530@22g2000hsm.googlegroups.com>
On 10 Jul., 15:06, Jeronimo Pellegrini <····@aleph0.info> wrote:

> So... Are structures really obsoleted by CLOS, or are structures
> actually more efficient in any way (speed, memory, whatever)?

The redefinition of structures is undefined and the CLtL2 section you
mentioned speaks about the intention of DEFSTRUCT to provide "the most
efficient" structure class. CL structures can be implemented using a
memory-layout more similar to C structures than to CLOS classes. If
you have a structure of 4 fixnums the memory-layout could look like
this:

Structure A
--------------------
Header:  00 00 00 00
Slot a:  00 00 00 00
Slot b:  00 00 00 00
Slot c:  00 00 00 00
Slot d:  00 00 00 00

Structure B (includes A)
------------------------
Header:  00 00 00 00
Slot a:  00 00 00 00
Slot b:  00 00 00 00
Slot c:  00 00 00 00
Slot d:  00 00 00 00
Slot e:  00 00 00 00
Slot f:  00 00 00 00

As you can see - the slots of the included structure A are encoded
directly in the memory layout of B. If you redefine A to have an
additional slot, the memory layout would be stale. One would have to
allocate more memory per instance which would change the identity of
all existing instances.

A typical CLOS instance could have a memory layout like this:

Class A
Header: 00 00 00 00
Class:  00 00 00 00
Slots:  00 00 00 00 -> Slot a: 00 00 00 00
                       Slot b: 00 00 00 00
                       Slot c: 00 00 00 00
                       Slot d: 00 00 00 00

And CLOS ensures internally that changes of the Class-Layout would
recompute the slot-vector. So only the "slots" slot in the Class-
Instance would be updated but the identity of the CLOS instance would
be the same.

So accesses to a structure instance could be equally fast like
accesses to a specialized array (e. g. non-boxed storage of objects
like DOUBLE-FLOAT) while CLOS slot accesses have a redirection through
the slots vector. On the other side: CLOS can optimize it's accessors
to directly access the current slot-vector which could lead to similar
performance. A change of the class layout would than entail the
recomputation of the accessor methods.

ciao,
Jochen
From: ·······@googlemail.com
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <1184084597.457870.7340@g4g2000hsf.googlegroups.com>
Is defun obsoleted by defmethod?
From: Willem Broekema
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <1184096558.100724.175600@k79g2000hse.googlegroups.com>
On Jul 10, 3:06 pm, Jeronimo Pellegrini <····@aleph0.info> wrote:
> "the macro DEFSTRUCT also defines new classes. But that's largely for
> backward compatibility -- DEFSTRUCT predated CLOS and was retrofitted
> do define classes when CLOS was integraded into the language."

This is a statement about the fact that if you use DEFSTRUCT, you
automatically define a class.  It is not saying anything about
classes /versus/ structs, and it in particular does not say that
structs are obsolete since the arrival of CLOS.


- Willem
From: Pascal Bourguignon
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <878x9onhn4.fsf@thalassa.lan.informatimago.com>
Willem Broekema <········@gmail.com> writes:

> On Jul 10, 3:06 pm, Jeronimo Pellegrini <····@aleph0.info> wrote:
>> "the macro DEFSTRUCT also defines new classes. But that's largely for
>> backward compatibility -- DEFSTRUCT predated CLOS and was retrofitted
>> do define classes when CLOS was integraded into the language."
>
> This is a statement about the fact that if you use DEFSTRUCT, you
> automatically define a class.  It is not saying anything about
> classes /versus/ structs, and it in particular does not say that
> structs are obsolete since the arrival of CLOS.

DEFSTRUCT doesn't always define a class (it may define lists or
vectors access functions).  

What's more, these classes are not standard-object classes, which has
some consequences...

C/USER[30]> (defstruct point x y)
POINT
C/USER[31]> (class-of (class-of (make-instance 'point)))
#<STANDARD-CLASS STRUCTURE-CLASS>
C/USER[32]> (defclass 3dpoint () (x y z))
#<STANDARD-CLASS 3DPOINT>
C/USER[33]> (class-of (class-of (make-instance '3dpoint)))
#<STANDARD-CLASS STANDARD-CLASS>
C/USER[34]> 

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: Tayssir John Gabbour
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <1184074888.427146.303850@g4g2000hsf.googlegroups.com>
On Jul 10, 3:06 pm, Jeronimo Pellegrini <····@aleph0.info> wrote:
> So... Are structures really obsoleted by CLOS, or are structures
> actually more efficient in any way (speed, memory, whatever)?

Structures are nice when dealing with someone's "poor man's objects"
in list or vector form. You know, when you see things like:

'((bob 555-2929 single)
  (jen 555-4930 married)
  (ted 555-4930 asexual))

If you don't want to rewrite it into CLOS, you could do something
like:

(defstruct (person (:type list))
  name phone romantic-relation)

(person-phone '(bob 555-2929 single))


That said, I prefer CLOS in the absence of a compelling reason to use
structs. (And maybe you use the MOP to gain more control of objects,
if you need the optimizations in a way which structs don't offer. But
I've never needed to do this, so can't speak from experience.)


Tayssir
From: Pascal Costanza
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <5fkad2F3cdj94U1@mid.individual.net>
Jeronimo Pellegrini wrote:
> Hi,
> 
> I have seen different kinds of advice on the use of structures and
> classes. For example, Peter Seibel mentions in PCL (page 204) that:
> 
> "the macro DEFSTRUCT also defines new classes. But that's largely for
> backward compatibility -- DEFSTRUCT predated CLOS and was retrofitted
> do define classes when CLOS was integraded into the language."

That's a good didactic explanation, but strictly not true. DEFSTRUCT 
didn't need to be changed to be supported by CLOS. Instead, CLOS's 
class-of treats non-CLOS instances specially.

> However, the style guide from the ALU at
> http://www.lisp.org/table/style.htm says:
> 
> "When you don't need the full power of CLOS, consider using structures
> instead. They are often faster, take up less space, and easier to use."
> 
> CLtL2 also has, on section 19.2:
> "The defstruct feature is intended to provide ``the most efficient''
> structure class"
> 
> So... Are structures really obsoleted by CLOS, or are structures
> actually more efficient in any way (speed, memory, whatever)?

In general, it is safe to just CLOS classes. They have better support 
for developing your software - you can change class definitions as you 
go which you allows you to grow your program without the need to restart 
everything from scratch for each and every change. CLOS classes are also 
more flexible and provide more functionality.

The advise to use defstruct in case you need more efficiency can be 
understood as: If you find out that some of your class definitions are 
bottlenecks, you can consider switching to a defstruct instead. With 
more experience, it will also become clear when to use what - there 
types/classes where the definitions are clear from the start and where 
it is also clear that you need a very simply data type, and then you can 
use defstruct.

It could have been interesting to deprecate defstruct and add more 
features to CLOS to tweak out more performance from CLOS classes (that's 
what Dylan did later on). But as things currently stand, I wouldn't 
consider defstruct obsolete.


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/
From: Thomas F. Burdick
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <1184177629.339828.178480@n2g2000hse.googlegroups.com>
On Jul 11, 5:13 pm, Pascal Costanza <····@p-cos.net> wrote:
> Jeronimo Pellegrini wrote:
> > Hi,
>
> > I have seen different kinds of advice on the use of structures and
> > classes. For example, Peter Seibel mentions in PCL (page 204) that:
>
> > "the macro DEFSTRUCT also defines new classes. But that's largely for
> > backward compatibility -- DEFSTRUCT predated CLOS and was retrofitted
> > do define classes when CLOS was integraded into the language."
>
> That's a good didactic explanation, but strictly not true. DEFSTRUCT
> didn't need to be changed to be supported by CLOS. Instead, CLOS's
> class-of treats non-CLOS instances specially.
>
> > However, the style guide from the ALU at
> >http://www.lisp.org/table/style.htmsays:
>
> > "When you don't need the full power of CLOS, consider using structures
> > instead. They are often faster, take up less space, and easier to use."
>
> > CLtL2 also has, on section 19.2:
> > "The defstruct feature is intended to provide ``the most efficient''
> > structure class"
>
> > So... Are structures really obsoleted by CLOS, or are structures
> > actually more efficient in any way (speed, memory, whatever)?
>
> In general, it is safe to just CLOS classes. They have better support
> for developing your software - you can change class definitions as you
> go which you allows you to grow your program without the need to restart
> everything from scratch for each and every change. CLOS classes are also
> more flexible and provide more functionality.

If you need to restart everything from scratch for each and every
change, you should switch implementations.  SBCL and CMUCL probably
have the best support for incremental development with structures:
upon incompatible redefinition, you can choose to either obsolete your
old instances and accessor functions, or proceed as though they were
compatible.  Allegro just redefines the layout and accessors, but
always bounds-checks access into the structure objects.

Both of these allow you to continue with your development, and only
occasionally can you get yourself in a tight spot.  No disagreement
that CLOS has great, portable, flexible redefinition semantics,
though.

> It could have been interesting to deprecate defstruct and add more
> features to CLOS to tweak out more performance from CLOS classes (that's
> what Dylan did later on). But as things currently stand, I wouldn't
> consider defstruct obsolete.

I think a perfectly nice option would have been just a tweak on the
existing state of the implementations (or at least the two I know
best).  If you could define structure-classes with defstruct, had
roughly the two choices that SBCL/CMUCL give you upon *incompatible*
redefinition, the implementations were required to quietly accept
compatible redefinitions, were required to bounds-check access even
when you pick SBCL/CMUCL choice #2, and slot-value and make-instance
were required to work with structure-objects and structure-classes
respectively.  Then you'd have good portable support for structure-
objects, with a painless upgrade path to standard-objects if you ever
need something fancier like MI, :around methods on accessors, or what
have you.  And then you could *truly* declare defstruct obsolete.
From: Jeronimo Pellegrini
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <f7fgn6$vnv$1@aioe.org>
On 2007-07-11, Pascal Costanza <··@p-cos.net> wrote:
> The advise to use defstruct in case you need more efficiency can be 
> understood as: If you find out that some of your class definitions are 
> bottlenecks, you can consider switching to a defstruct instead. With 
> more experience, it will also become clear when to use what - there 
> types/classes where the definitions are clear from the start and where 
> it is also clear that you need a very simply data type, and then you can 
> use defstruct.

Thanks everyone for all the explanations.

I have done some tests with SBCL, and it seems that accessing structures
really is more efficient. Actually, the time to access classes and
structures on my system are roughly proportional to:

- methods on classes      2.0
- functions on classes    1.5
- methods on structures   0.9
- functions on structures 0.7

Since all I want to do is to loop over arrays and hashtables
inside the class/structure, I should get a reference to the array once,
and then loop -- and not do something like

(dotimes (...)
  (...
    (get-value (myinstance index))))

J.
From: Chris Parker
Subject: Re: Are structures obsoleted by CLOS?
Date: 
Message-ID: <1184544941.322966.66300@z28g2000prd.googlegroups.com>
On Jul 10, 8:06 am, Jeronimo Pellegrini <····@aleph0.info> wrote:
> Hi,
>
> I have seen different kinds of advice on the use of structures and
> classes. For example, Peter Seibel mentions in PCL (page 204) that:
>
> "the macro DEFSTRUCT also defines new classes. But that's largely for
> backward compatibility -- DEFSTRUCT predated CLOS and was retrofitted
> do define classes when CLOS was integraded into the language."
>
> However, the style guide from the ALU athttp://www.lisp.org/table/style.htmsays:
>
> "When you don't need the full power of CLOS, consider using structures
> instead. They are often faster, take up less space, and easier to use."
>
> CLtL2 also has, on section 19.2:
> "The defstruct feature is intended to provide ``the most efficient''
> structure class"
>
> So... Are structures really obsoleted by CLOS, or are structures
> actually more efficient in any way (speed, memory, whatever)?
>
> Thanks,
> J.

I think that they are.