* 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).