mop for structures

Bug #894241 reported by sds
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
New
Wishlist
Unassigned

Bug Description

* (defstruct s a)
S
* (sb-pcl:class-direct-slots (find-class 's))
(#<SB-PCL::STRUCTURE-DIRECT-SLOT-DEFINITION A>)
* (sb-pcl:slot-definition-initargs (car *))
NIL

I expected (:A) to be returned by the last form; that's what I get with clisp:

[1]> (defstruct s a)
S
[2]> (clos:class-direct-slots (find-class 's))
(#<CLOS::STRUCTURE-DIRECT-SLOT-DEFINITION A #x000333F99788>)
[3]> (clos:slot-definition-initargs (car *))
(:A)

same for reader et al.
SBCL 1.0.50.0.debian

Revision history for this message
Christophe Rhodes (csr21-cantab) wrote : Re: [Bug 894241] [NEW] mop for structures

sds <email address hidden> writes:

> Public bug reported:
>
> * (defstruct s a)
> S
> * (sb-pcl:class-direct-slots (find-class 's))
> (#<SB-PCL::STRUCTURE-DIRECT-SLOT-DEFINITION A>)
> * (sb-pcl:slot-definition-initargs (car *))
> NIL

I think both this and the answer from clisp are consistent with their
respective implementations of MAKE-INSTANCE: in SBCL, after the above,
  (make-instance 's :a 3)
signals an invalid initarg error, while in clisp the same form returns
#S(S :A 3). So I think what's needed is to take a step back and ask
whether either of these behaviours of MAKE-INSTANCE given just a
structure definition is more desireable. I think it's right not to
return S-A as a reader for the slot, because I would expect to be able
to define auxiliary methods on reader functions, but of course the
struct-generated one isn't a generic function.

Getting a real initarg in sbcl can be done with
  (defclass s ()
    ((a :initarg :a))
    (:metaclass structure-class))

Cheers,

Christophe

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

I've been thinking of this on and off.

The benefit of our current "defstruct initiargs aren't make-instance initargs" approach is that makes it more likely to pinpoint places where you've left a make-instance in place after switching to structs.

The benefit of allowing defstruct initargs to be used with make-instance is that it makes switching between the two definitions less painful.

Given that our current approach doesn't guarantee catching all such sites anyhow, but adding an error-signaling method on eg. initialize-instance does[*] ... I think I'm in favor of allowing defstruct initargs in make-instance.

Anyone else?

[*] Assuming tests with complete coverage, it's not like either method works statically.

Revision history for this message
sds (sds-gnu) wrote : Re: [Bug 894241] Re: mop for structures

> * Nikodemus Siivola <email address hidden> [2012-04-19 12:47:54 +0000]:
>
> The benefit of our current "defstruct initiargs aren't make-instance
> initargs" approach is that makes it more likely to pinpoint places
> where you've left a make-instance in place after switching to structs.

and how valuable would this be?
after all, this is a run-time detection!
you can do better before even compiling - using grep!
(that is, if the class name in the make-instance call is a constant; if
it is dynamically constructed, then the switch to defstruct become much
more complicated).

> The benefit of allowing defstruct initargs to be used with make-instance
> is that it makes switching between the two definitions less painful.

Precisely! defstruct is just a cheap way to define objects, a
quick-and-dirty alternative to defclass for interactive experimentation,
their killer feature is the automatic readable printability;
the more advanced features are available for defstruct, the better.

> Given that our current approach doesn't guarantee catching all such
> sites anyhow, but adding an error-signaling method on eg. initialize-
> instance does[*] ... I think I'm in favor of allowing defstruct
> initargs in make-instance.

good.
you might want to consider implementing The structure Meta-Object Protocol
http://clisp.org/impnotes/defstruct-mop.html
--
Sam Steingold (http://sds.podval.org/) on Ubuntu 11.10 (oneiric) X 11.0.11004000
http://www.childpsy.net/ http://memri.org http://iris.org.il
http://www.memritv.org http://thereligionofpeace.com http://honestreporting.com
To be popular with ladies one has to be smart, handsome & rich. Or to be a cat.

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

Heh, from my perspective the killer features of DEFSTRUCT (and DEFSTRUCT constructors) are

- slot access speed
- potential for stack allocation
- additional type safety thanks (way, way easier for the compiler to derive types when defstructs are involved)
- unboxed slots

Stas Boukarev (stassats)
Changed in sbcl:
importance: Undecided → Wishlist
Revision history for this message
Christophe Rhodes (csr21-cantab) wrote : Re: [Bug 894241] [NEW] mop for structures

sds <email address hidden> writes:

> * (defstruct s a)
> S
> * (sb-pcl:class-direct-slots (find-class 's))
> (#<SB-PCL::STRUCTURE-DIRECT-SLOT-DEFINITION A>)
> * (sb-pcl:slot-definition-initargs (car *))
> NIL
>
> I expected (:A) to be returned by the last form

I'm not sure why this is expected. The initargs relate to arguments to
make-instance, not to any structure constructor, and sbcl does not
define any initargs from defstruct forms. I'm particularly not
convinced that the inclusion of the structure accessor in
slot-definition-readers is sensible, given that I would expect that the
readers to name generic functions (and structure accessors from
defstruct in sbcl are not generic). In other words, sbcl's mop for
structures is consistent in this respect.

If you need a structure with generic accessors and initargs for
make-instance, the portable way to do that is with defclass and
:metaclass structure-class.

Christophe

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.