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: should GOOPS be built-in?


Michael Vanier <mvanier@bbb.caltech.edu> writes:

> No offense meant, of course.

I think you raise questions which are valid in themselves.  It was
wrong of me just to dismiss them the way I did.  It's just that I know
that it is a good decision to incorporate GOOPS into the core, and I
didn't have patience (or time!) to enter the debate which I expected
to be ignited by your posting.

So, I'm clearly the one who should apologize.

> > Code more, talk less!

This was not aimed at you in particular but was meant as a general
exclamation.

> However, assuming GOOPS is built-in, how does this affect the
> possibility of adding/using alternative object systems that provide
> more information-hiding than GOOPS-type object systems do?  This
> *will* be an issue where translators are concerned, and maybe even
> independently of that.

As others have said already supporting GOOPS in the core will
certainly not make it harder to add other object systems.  It's
probably the other way around.  We'll still have the option of either
adding/using an entirely different object system or emulating it in
GOOPS.

I'll show you an example of how the MOP in GOOPS can be used to adapt
it's behaviour.  (I discovered a few bugs while writing this example,
so you'll have to use the very latest source from CVS for it to work.)

Imagine that we have a class library L exporting the class c:

(define-module (L)
  :use-module (oop goops))

(export c b)

(define-class c ()
  (a #:accessor a #:init-value 1)
  (b #:accessor b #:init-value 2))

Note how we leave the task of information hiding to the module system:
b is made public since it is exported, while a is private.  (Maybe we
should add a keyword #:public-accessor which does the export
automatically?)

Now, imagine that we use L this way:

(use-modules (oop goops) (L))

(define-class d (c)
  (a #:accessor a #:init-value 3))

In GOOPS, you are supposed to know which slots the class c has, so the
slot a in d should not be interpreted as a new slot but rather as a
redefinition of the slot a in c.  This is probably the problem of
information hiding which you are referring to.  Am I right?

Suppose that we don't want to know about the "private" slots in c and
would like the definition of a in d to really be a new slot.  In this
case, we need to alter the way new slots are computed when new classes
are created.  We can do this by using the MOP:

(define-module (oop goops rigid-class)
  #:use-module (oop goops))

(export <rigid-class> define-rclass)

(define-class <rigid-class> (<class>))

(define-method compute-slots ((c <rigid-class>))
  ;; The order is selected so that `slot-ref' will hit the
  ;; direct slots first.
  (apply append (class-direct-slots c)
	 (map class-slots (class-direct-supers c))))

(define-macro (define-rclass . stuff)
  `(define-class ,@stuff #:metaclass <rigid-class>))

Now we can write:

(use-modules (oop goops rigid-class))

(define-rclass d (c)
  (a #:accessor a #:init-value 3))

(define o (make d))

And, voila, (a o) will yield 1 inside module (L) and 3 in the current
module as we wanted.

We still have the problem that slot-ref can access private slots,
however, but this can be fixed in a similar way, and let
`compute-slots' rename the private slots.

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