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:

> Mikael Djurfeldt <mdj@mdj-pc.nada.kth.se> writes:
> 
> > Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE> writes:

[...]

> Are there any papers that discuss the advantages and disadvantages
> of these two approaches?

No such reference come to my mind right now.  I think there is a
discussion about this in the Dylan manual.  There were also many
discussions on this topic in comp.lang.scheme a few years ago.  Maybe
you can find something in the archives.

Does someone else have a reference?

> As I understand the CLOS paradigm, the state of an object O
> belonging to class C can be manipulated by a function that doesn't
> necessarily belong to C.

In the CLOS paradigm, there is no such thing as a function belonging
to a class.  There are operations and types.  Consider the operation
`*'.  We specialize it to the types <matrix> and <vector>:

(define-method * ((A <matrix>) (x <vector>))
  ...)

Does this method belong to <matrix> or <vector>?  Neither!  It is one
special case of how to multiply, so the method belongs to the generic
function *.

> Such a function operating on the state of a foreign class' object
> breaks the class boundary and creates a side effect.

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.

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

> A module can't protect a class if there is more than one class located
> in the module.  That means that there is exactly one class per module.
> I think here is a redundancy.  A module imports definitions
> from other modules and a class imports (extends) other classes.  
> When you want to write a class that extends the class X located in module MX
> you must write down the same information twice: 1) use module MX, 2) 
> derive from class X.
> 
> Java and the system designed by Matthias Blume doesn't use modules
> at all.  Instead it is possible to design a *module as a special kind of class*:
> A module is a class with exactly one instance.

I think you have an important point here.  I agree that there are
similarities in the semantics of a module system and an object system
and it is certainly elegant to combine them.

I think we should continue to ponder on how to integrate these two
concepts in Scheme.

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.

I would guess that it is possible to integrate his system with GOOPS
in a smooth way.  In fact, his system might provide exactly the things
we need to support efficient compilation of GOOPS code in a clean way.
(But it might cause problems that GOOPS uses types which are first
class objects.)

> My idea is:

[...]

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.  I'm sure that this could be done, and that the result
would have it's points.

Just a couple of comments:

> (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.  I think:

  (color fc1)

id more consistent with Scheme.  Color represents the operator which
maps an object to its color.

What is even more disturbing is that all expressions which access
members of objects would be special forms in your syntax.  This is
simply not acceptable.  You want to be able to do things like (GOOPS
code)

  (define (colors objects)
    (map color objects))

How would you do this in your system?

Also, if a above would have been a "method", the expression would have
been

  ((m1 a) arg1 arg2)

I'm afraid that code might become messy with this syntax.  Compare to
the GOOPS syntax:

  (a m1 arg1 arg2)

> (m1 a 1)                                (fc1 color 1)

Don't you think

  (set! (m1 a) 1)

more clearly expresses the action of setting a variable?

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

> It would be nice if we could design a low level OO interface and
> plant GOOPS and possibly other OO interfaces on top of it.

Yes, that would be nice.

However, to me, the task seems overwhelming.  Please read the file
tiny-clos.rpp from the tiny-clos package (available at the scheme
repository).  It demonstrates the beauty of the MOP which in one can
be seen as a description of the system in terms of itself, and, more
importantly, is a powerful way to customize the object system to the
needs of the user.

The task of designing a MOP with great power, but which also allows
for an efficient implementation is in itself very difficult.  The
problem is that if you introduce the kind of low-level interface you
ask for, it either would involve the MOP, which would complicate it,
or would prevent the MOP from being efficient.

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.

It is my view that we should concentrate on GOOPS right now, but keep
your thoughts in the back of our heads.

> > 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 guess the choice was made because the type information is usually
 stored in the CAR, and because it must be quickly accessible.
 It does complicate things, and we won't keep that representation.)

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