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


Mikael Djurfeldt <mdj@thalamus.nada.kth.se> writes:


> (define-method * ((A <matrix>) (x <vector>))
>   ...)
> 
> Does this method belong to <matrix> or <vector>?  Neither! 

<product>.multiply(<factor>, <factor>);

The method `*' clearly belongs to the class <product>.  One can say that
the class <product> modifys itself.  In any case, its methods can't
modify instances of other classes!

When you write (* <matrix> <vector>) this is either a functional style
(i.e. the function returns a value) or it is OO style (i.e. the method
manipulates a data structure).

In the above example it is obvious that A is manipulated but
what about the following (silly) example:

(define-method m ((B <t2>) (A <t1>)))

What does the method `m' do?  Does it return a value, does it
manipulate B or does it manipulate A?



> I don't understand what you mean here.  OOP usually is imperative and
> it is common for methods to have side effects.  But this is true
> regardless if you associate methods with generic functions or
> classes.

In the OO paradigm you don't associate methods with classes.  They
*belong* to exactly one class' object and they will go away when
the object goes away.


> > This may not be a big problem since each class belongs to a certain
> > module and the accessor (get/set*) functions are created within this
> > module so that the module can and will protect the class' objects and 
> > exports the accessor functions.  Right? 
> 
> Well, you have to explain the problem first, because I don't see it.

Protection.  How can one prevent a method from accidently modifying
several objects. How can one hide slots from beeing touched by foreign
methods?  Removing the slot-ref/set! functionality and letting the
surounding module handle protection (the module exports the getter/set
methods) seems to be a good choice.

The problem is that this introduces redundancy.  The class "knows"
which other classes it needs.  But the module doesn't know that.
Therefore you have to type the same information twice: Class c extends
class a and therefore you must tell the current module C to import the
class a from module A.


> You speak strangely about Matthias Blume.  If I remember correctly,
> his proposal *is* in fact a module system.  He addresses the question
> how to specify module interfaces in a way so that you can do separate
> compilation of modules with optimization based on type analysis.

Yes.  His paper is about a type system with inheritance.  Normally a
type system is ortogonal to a module system: The type system handles
the logical structure of the software and the module system handles
the physical structure.

But he treats modules just like classes and I quite like the trick.
Normaly a module /owns/ one or more classes.  In his system a module
/is a/ class.


> I think I see what you mean.  You think Matthias system is close
> enough to an object system, and is considering modifying it slightly
> to become one. 

Not quite.  I am searching for a way to smoothly integrate an object
system into the module system.  This is part of my "porting goops to
the new environment-system" effort. :)  Although GOOPS is the only 
OO system we have at the moment I want to keep the interface as 
open as possible.


> (m1 a) -> 2                             (fc1 color) -> 1
> 
> In a way, I think this syntax is disturbing.  In Scheme, I'm used that
> the first element in an expression is an operator.  But here, fc1 is
> in fact an object.

Yes.  But as Craig already said: "Natural is a POV issue." :)


>   (define (colors objects)
>     (map color objects))
> 
> How would you do this in your system?

Ah.  You can't.  But since the object fc1 is a lambda you can pass
it as an argument.

But you can't hide the fact that the OO paradigm turns the
generic style used in scheme upside down (the explicit type
system is another example).  


> Also, if a above would have been a "method", the expression would have
> been
> 
>   ((m1 a) arg1 arg2)

a can either be a method, a "getter" or "setter" or a slot.  m1 can and will
handle all these cases correctly.  But it is true that you must
quote the selector `a' which is simply a symbol.

> There is the risk of getting confused when the only difference between
> assignment and reference is the number of elements in the application.

A method with no arguments returns the slot (is a getter) or a setter
with an implicit argument, for example (fc1 'set-color-to-1).  A method
with 3 or more arguments is a always setter.


> But, the MOP *does* give you power to "imitate" other object system,
> so in a sense, you can use the MOP instead of the low level interface
> you request.

GTK for example has a nice C level OO system with single inheritance.
I think I'll take a look at what features are common to GTK and GOOPS
by using Eiffel as a reference.  We'll see. :)


> It is my view that we should concentrate on GOOPS right now

Yes.


 > > 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.
> > 
> > Okay.  But why is the layout stored in the car?  Isn't is sufficient to
> > just store the pointer to the layout in the cdr?  
> 
> When you say "layout", I assume that you mean "type" (or more
> precisely "vtable").
> 
> Why do you ask?  It needs to be stored somewhere.

I would store it in the superclass i.e. the struct that describes the
current struct.  But this has the problem that when our superclass
goes away our class won't find its type anymore.  I think that's why
the type is duplicated (stored in the cdr of the superclass and in the
car of our class).


Jost

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