This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Some questions about GOOPS and CLOS in general


Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE> writes:

> last weekend I looked at the guile OO system "goops" which implements
> the CLOS OO paradigm.  Maybe someone could answer me the following
> (probably silly) questions:
> 
> * The class X inherits features from two unrelated classes piano and bike.
>   (I don't have a better example at the moment :>)
>   Both classes A and B export a feature with the name "pedal".
>   How can X access the feature "pedal" inherited from piano *and*
>   the feature "pedal" inherited from bike?
>   In most other OO languages it is possible to rename a feature
>   inherited from a super class.  Is this possible in GOOPS?

The name `pedal' will refer to a single feature `pedal' in X, i.e.,
the slots are merged.

This means that a programmer need to be aware of what slots are used
by the class libraries he use in his program.

This is of course not nice.  It means that you can't use the full
power of data abstraction and it makes it difficult to re-use code.

I have a plan to fix this in a way which is compatible with STKlos: I
intend to introduce slot classes and extend the meta object protocol
in a way that we can choose whether to merge slots or allow multiple
slots with the same name.  The default will be not to merge.  If you
are useing the STk compatibility module, the default will be to merge.

This extension will allow us to represent classes more compactly and
will actually make slot access faster as nice side effects.  It will
also make it possible for the user to tailor the behaviour of the
object system to a greater extent when he is adapting it for his
application.

> * The interface seems rather strange to me. For example
>   GOOPS uses getter and setter functions to access slots.
>   A more "natural" way would be:
>   (<class> <constructor> args) -> <object>
>   (<object> <feature>) -> get value ("getter")
>   (<object> <feature> args) ->  set value ("setter")

There are roughly two camps in the "OOP community": Those who collect
methods in classes and those who collect methods in generic functions.

It is possible to talk very long about the advantages/disadvantages of
each approach.  I won't do that here.  I just note that Dylan chose
the second approach.

(Also, GOOPS actually can be customized to behave the way you describe
 using the MOP. :)

> * In CLOS classes don't own (polymorphic) methods.  Instead
>   it is possible to associate a polymorphic method called "generic"
>   to a class.  The problem is, that it is not possible to
>   "ask" a class about the methods it supports.  For example
>   if you want to write a class that stores itself onto 
>   a persistent store, the class has now way to store the
>   methods associated with it.

I think you've got the answer to this one.  It is basically that
you're requesting a feature which belongs to a different paradigm.
I'll just add that there is a selector `class-methods' which can be
handy during debugging, and which possibly could be used when

> * The CALL_GF1 macros.  These macros look up variables on
>   module level and then call methods stored in these variables.
>   The environment cache update and unmemoization protocol will
>   notify goops when their locations change (goops registers
>   observer procedures with env-observe-weak() etc.).
>   No problem so far.
> 
>   The problem I see is that goops doesn't specify in which module
>   (in which environment) these variables should be looked up.
>   The current module system uses a state variable which tracks
>   the "current module".  The module_lookup_closure looks up
>   symbols in the "current module".
>   Unfortunately (or fortunately :>) the new module system 
>   is state-less.  There is no such thing as "the current module".
>   If you want to evaluate an expression or look up a variable you
>   must specify in which environment you want to evaluate the 
>   expression or look up the variable.

The CALL_GF1 macros look up the generic functions in the (oop goops)
module, not "the current module", so there should be no problem.
(BTW, I'd like to add that there are still pieces of code remaining in
GOOPS where I chose to make a minimal change of the original code in
order to get GOOPS in the air quickly.  This should not affect GOOPS
function, though.)

> * I don't understand the structures at all!  Why do structures have
>   the type cm_tc3_cons_gloc?  I do understand that the car of the
>   structure specifies the layout of it's cdr.  And the cdr's layout
>   is the template for a new struct (the sub-type) and copied to the car
>   of the new struct.  Why so complicated?  

Structs are currently the current basic record type in Guile.  I
didn't implement them (although I have made some extensions) so I
really can't give motivations for their implementation.  In my
personal opinion they are terribly ugly, but still they have some nice
features which we should learn from in the new record implementation.

Structs will be replaced, so you probably shouldn't spend too much
time on them.

To try to answer your question: A layout is info for the GC what to
protect and not and is stored in the type of a struct.  The
inheritance structure of structs is similar to the inheritance
structure in CLOS, only that it is single.  An object has a class.
The class of an object is itself an object of the class class (the
class class is the metaclass of the class of the object).  The class
class is an object of the class class, i.e. of itself.  Similarly, a
struct has a type (CAR), which itself is a struct.  The type of this
stuct is a vtable, i.e. a struct which has itself as type.  The
relations of the layouts follow from this.

> * The class' slots seems to be implemented as a list.  Isn't it possible to
>   store them directly into the class?

Strictly, they don't belong there since the class object is only a
description of a type of instances.  (Tiny-clos, is a small
scheme-adapted implementation of CLOS.  It is truly enlightening to
study it.)

In any case, they are actually implemented as a local binding which is
reasonably efficient.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]