unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* goops proposal: proper struct classes
@ 2011-05-01 20:19 Andy Wingo
  2011-05-05 16:35 ` Ludovic Courtès
  2011-11-22 22:23 ` Andy Wingo
  0 siblings, 2 replies; 6+ messages in thread
From: Andy Wingo @ 2011-05-01 20:19 UTC (permalink / raw)
  To: guile-devel

Hello all,

If you know GOOPS, then you know that we have classes, rooted at
<class>.  And indeed <class> shows up a lot in documentation and in
code.  But that's not how it is in CLOS: our <class> corresponds to
their `standard-class'.  They have a superclass, called `class', which
is the real root, and from which e.g. structure classes are derived.

We need to do this.  Currently, class-of on a struct/record data type
gives a useless class that can't instantiate instances, doesn't know its
slots, and does not reflect the vtable hierarchy.

So we need a <basic-class>, interposed between <class> and <object>,
which will be the real root of our class meta-object hierarchy.

I noticed this while fixing some weak hash table-related bugs today, and
I saw set-struct-vtable-name!, which ends up causing some crazy stuff to
happen (exporting a stub class from (oop goops)), and noticed how wrong
all this was.

Comments?

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: goops proposal: proper struct classes
  2011-05-01 20:19 goops proposal: proper struct classes Andy Wingo
@ 2011-05-05 16:35 ` Ludovic Courtès
  2011-05-05 18:25   ` Andy Wingo
  2011-11-22 22:23 ` Andy Wingo
  1 sibling, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2011-05-05 16:35 UTC (permalink / raw)
  To: guile-devel

Hi Andy,

Andy Wingo <wingo@pobox.com> writes:

> If you know GOOPS, then you know that we have classes, rooted at
> <class>.  And indeed <class> shows up a lot in documentation and in
> code.  But that's not how it is in CLOS: our <class> corresponds to
> their `standard-class'.  They have a superclass, called `class', which
> is the real root, and from which e.g. structure classes are derived.
>
> We need to do this.  Currently, class-of on a struct/record data type
> gives a useless class that can't instantiate instances, doesn't know its
> slots, and does not reflect the vtable hierarchy.

Here’s an illustration:

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> (use-modules (oop goops) (srfi srfi-9))
scheme@(guile-user)> (define-record-type <foo> (make-foo x) foo? (x foo-x))
scheme@(guile-user)> (make-foo 2)
$3 = #<<foo> x: 2>
scheme@(guile-user)> (class-of $3)
$4 = #<<class> <> 148a4b0>
scheme@(guile-user)> (class-slots $4)
$5 = ()
scheme@(guile-user)> (class-of $4)
$6 = #<<class> <class> 8e7a50>
--8<---------------cut here---------------end--------------->8---

> So we need a <basic-class>, interposed between <class> and <object>,
> which will be the real root of our class meta-object hierarchy.

Why?

Couldn’t ‘scm_i_define_class_for_vtable’ build a full-blown class,
populating its CPL, its ‘slots’ slot, etc.?

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: goops proposal: proper struct classes
  2011-05-05 16:35 ` Ludovic Courtès
@ 2011-05-05 18:25   ` Andy Wingo
  2011-05-05 20:19     ` Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Andy Wingo @ 2011-05-05 18:25 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

Hi :)

On Thu 05 May 2011 18:35, ludo@gnu.org (Ludovic Courtès) writes:

> Andy Wingo <wingo@pobox.com> writes:
>
>> If you know GOOPS, then you know that we have classes, rooted at
>> <class>.  And indeed <class> shows up a lot in documentation and in
>> code.  But that's not how it is in CLOS: our <class> corresponds to
>> their `standard-class'.  They have a superclass, called `class', which
>> is the real root, and from which e.g. structure classes are derived.
>>
>> We need to do this.  Currently, class-of on a struct/record data type
>> gives a useless class that can't instantiate instances, doesn't know its
>> slots, and does not reflect the vtable hierarchy.
>
> Here’s an illustration:
>
> scheme@(guile-user)> (use-modules (oop goops) (srfi srfi-9))
> scheme@(guile-user)> (define-record-type <foo> (make-foo x) foo? (x foo-x))
> scheme@(guile-user)> (make-foo 2)
> $3 = #<<foo> x: 2>
> scheme@(guile-user)> (class-of $3)
> $4 = #<<class> <> 148a4b0>

Here it probably should have a name, even now; probably a bug, that
srfi-9 should call set-struct-vtable-name! on the rtd.

> scheme@(guile-user)> (class-slots $4)
> $5 = ()
> scheme@(guile-user)> (class-of $4)
> $6 = #<<class> <class> 8e7a50>

Here's the problem, for me: 

    scheme@(guile-user)> (define-record-type <foo> (make-foo x) foo? (x foo-x))
    scheme@(guile-user)> (make-foo 10)
    $1 = #<<foo> x: 10>
    scheme@(guile-user)> (struct-vtable $1)
    $2 = #<vtable:2356fa0 pruhsruhpwphuhuh 6a55640>
    scheme@(guile-user)> (struct-vtable $2)
    $3 = #<vtable:2356fa0 pruhsruhpwphuhuh 2356fa0>
    scheme@(guile-user)> (struct-vtable $3)
    $4 = #<vtable:2356fa0 pruhsruhpwphuhuh 2356fa0>

See?  The struct's vtable is actually an instance of another vtable --
of another class -- and that metaclass is a vtable-vtable (because $3
and $4 are equal).

So class-of $2 should yield the class-of $3, which is actually some
other bug:

    scheme@(guile-user)> (class-of $2)
    $5 = #<<class> <> 368e870>
    scheme@(guile-user)> (class-of $3)
    $6 = #<<class> <> 368e870>

>> So we need a <basic-class>, interposed between <class> and <object>,
>> which will be the real root of our class meta-object hierarchy.
>
> Why?
>
> Couldn’t ‘scm_i_define_class_for_vtable’ build a full-blown class,
> populating its CPL, its ‘slots’ slot, etc.?

Yes, it could.  I didn't mention that.  I think that such a duplicate
hierarchy is unnecessary, because we can define methods for some of the
class protocol (class-name at least!).

Vtables *are* classes, on a fundamental level.  Bare vtables are not as
nice as <class>, but they do describe instances.  SCM_CLASS_OF() is
SCM_STRUCT_VTABLE().

WDYT?  Am I off the deep end again? :)

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: goops proposal: proper struct classes
  2011-05-05 18:25   ` Andy Wingo
@ 2011-05-05 20:19     ` Ludovic Courtès
  2011-05-05 20:39       ` Andy Wingo
  0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2011-05-05 20:19 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Hey!

Andy Wingo <wingo@pobox.com> writes:

> Here's the problem, for me: 
>
>     scheme@(guile-user)> (define-record-type <foo> (make-foo x) foo? (x foo-x))
>     scheme@(guile-user)> (make-foo 10)
>     $1 = #<<foo> x: 10>
>     scheme@(guile-user)> (struct-vtable $1)
>     $2 = #<vtable:2356fa0 pruhsruhpwphuhuh 6a55640>
>     scheme@(guile-user)> (struct-vtable $2)
>     $3 = #<vtable:2356fa0 pruhsruhpwphuhuh 2356fa0>
>     scheme@(guile-user)> (struct-vtable $3)
>     $4 = #<vtable:2356fa0 pruhsruhpwphuhuh 2356fa0>
>
> See?  The struct's vtable is actually an instance of another vtable --
> of another class -- and that metaclass is a vtable-vtable (because $3
> and $4 are equal).
>
> So class-of $2 should yield the class-of $3, which is actually some
> other bug:
>
>     scheme@(guile-user)> (class-of $2)
>     $5 = #<<class> <> 368e870>
>     scheme@(guile-user)> (class-of $3)
>     $6 = #<<class> <> 368e870>

Yes, understood.

>>> So we need a <basic-class>, interposed between <class> and <object>,
>>> which will be the real root of our class meta-object hierarchy.
>>
>> Why?
>>
>> Couldn’t ‘scm_i_define_class_for_vtable’ build a full-blown class,
>> populating its CPL, its ‘slots’ slot, etc.?
>
> Yes, it could.  I didn't mention that.  I think that such a duplicate
> hierarchy is unnecessary, because we can define methods for some of the
> class protocol (class-name at least!).

So that would mean getting rid of ‘scm_i_define_class_for_vtable’
altogether, and instead have vtables directly behave as classes, right?

> Vtables *are* classes, on a fundamental level.  Bare vtables are not as
> nice as <class>, but they do describe instances.  SCM_CLASS_OF() is
> SCM_STRUCT_VTABLE().

OK, it would be more elegant.

Can it be achieved without GOOPsifying too much the rest of Guile?
I mean, creating and accessing raw structs should remain as lightweight as
currently, so that syntactic-only records à la SRFI-9 can be
implemented.  GOOPS objects are currently heavyweight compared to raw
structs.

Thanks,
Ludo’.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: goops proposal: proper struct classes
  2011-05-05 20:19     ` Ludovic Courtès
@ 2011-05-05 20:39       ` Andy Wingo
  0 siblings, 0 replies; 6+ messages in thread
From: Andy Wingo @ 2011-05-05 20:39 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

On Thu 05 May 2011 22:19, ludo@gnu.org (Ludovic Courtès) writes:

>> Vtables *are* classes, on a fundamental level.  Bare vtables are not as
>> nice as <class>, but they do describe instances.  SCM_CLASS_OF() is
>> SCM_STRUCT_VTABLE().
>
> OK, it would be more elegant.
>
> Can it be achieved without GOOPsifying too much the rest of Guile?
> I mean, creating and accessing raw structs should remain as lightweight as
> currently, so that syntactic-only records à la SRFI-9 can be
> implemented.  GOOPS objects are currently heavyweight compared to raw
> structs.

Yes, I think it can.  Actually the motivation was to remove the call to
scm_i_define_class_for_vtable from structs, which will allow proper
layering of goops and structs.  (You are right to be concerned, I think;
GOOPS is pretty neat to have, and appropriate to some domains, but has
fundamental problems with modularity.)

Cheers,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: goops proposal: proper struct classes
  2011-05-01 20:19 goops proposal: proper struct classes Andy Wingo
  2011-05-05 16:35 ` Ludovic Courtès
@ 2011-11-22 22:23 ` Andy Wingo
  1 sibling, 0 replies; 6+ messages in thread
From: Andy Wingo @ 2011-11-22 22:23 UTC (permalink / raw)
  To: guile-devel

Hi,

Just some more details here, to get this off the back of my queue:

On Sun 01 May 2011 22:19, Andy Wingo <wingo@pobox.com> writes:

> If you know GOOPS, then you know that we have classes, rooted at
> <class>.  And indeed <class> shows up a lot in documentation and in
> code.  But that's not how it is in CLOS: our <class> corresponds to
> their `standard-class'.  They have a superclass, called `class', which
> is the real root, and from which e.g. structure classes are derived.

From CLISP:

    [1]> (defstruct foo)
    FOO
    [2]> (class-of (make-foo))
    #<STRUCTURE-CLASS FOO>
    [3]> (class-of (class-of (make-foo)))
    #<STANDARD-CLASS STRUCTURE-CLASS>
    [4]> (class-precedence-list (class-of (make-foo)))
    (#<STRUCTURE-CLASS FOO> #<STRUCTURE-CLASS STRUCTURE-OBJECT>
     #<BUILT-IN-CLASS T>)
    [5]> (class-precedence-list (class-of (class-of (make-foo))))
    (#<STANDARD-CLASS STRUCTURE-CLASS>
     #<STANDARD-CLASS CLOS::SLOTTED-CLASS>
     #<STANDARD-CLASS CLASS>
     #<STANDARD-CLASS CLOS::POTENTIAL-CLASS>
     #<STANDARD-CLASS SPECIALIZER>
     #<STANDARD-CLASS CLOS::SUPER-CLASS>
     #<STANDARD-CLASS STANDARD-STABLEHASH>
     #<STANDARD-CLASS METAOBJECT>
     #<STANDARD-CLASS STANDARD-OBJECT>
     #<BUILT-IN-CLASS T>)

> We need to do this.  Currently, class-of on a struct/record data type
> gives a useless class that can't instantiate instances, doesn't know its
> slots, and does not reflect the vtable hierarchy.

A slightly different case, but FWIW:

    scheme@(guile-user)> (class-precedence-list (class-of 1))
    $1 = (#<<class> <integer> 17ad960>
          #<<class> <real> 17ada50>
          #<<class> <complex> 17adb40>
          #<<class> <number> 17adc30>
          #<<class> <top> 1172690>)
    scheme@(guile-user)> (class-precedence-list (class-of (class-of 1)))
    $2 = (#<<class> <class> 1172780>
          #<<class> <object> 11725a0>
          #<<class> <top> 1172690>)

> So we need a <basic-class>, interposed between <class> and <object>,
> which will be the real root of our class meta-object hierarchy.

This is almost right: we do need <basic-class> in the cpl between
<class> and <object>, but <class> (and <basic-class> and, later,
<struct-class>) should still be an instance of <class>.

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-11-22 22:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-01 20:19 goops proposal: proper struct classes Andy Wingo
2011-05-05 16:35 ` Ludovic Courtès
2011-05-05 18:25   ` Andy Wingo
2011-05-05 20:19     ` Ludovic Courtès
2011-05-05 20:39       ` Andy Wingo
2011-11-22 22:23 ` Andy Wingo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).