From: Fernando Mato Mira
Subject: Encapsulating CLOS (was: Diff. CLOS  vs  C++)
Date: 
Message-ID: <2fc4f0$8p3@disuns2.epfl.ch>
In article <··········@disuns2.epfl.ch>, I wrote:
   [a lot of package hacks deleted]

(In the following, I assume a package per class, and might
 use a class name as the name of its associated package).

There is one big problem with the scheme I described:
Given a class X with subclasses Y, where a symbol
S is exported from X and unexported from Y,
if you (USE-CLASS 'Y), now you have to write
 (slot-value x 'X:S)

Now, referring to X:S seems completely OK, after all
it is an exported symbol. However, if x is happens
to be of type Y, you're being allowed to do exactly
what we try to prevent.
The problem is even worse if you have another subclass
of X (say, Z) where S is not unexported, as evaluating
 (USE-CLASS 'Z) would now intern X:S again, and you
could write (slot-value x 'S), which is right for
X and Z, but totally wrong for Y.

Now, I have been thinking about the slot renaming issue
ever since I moved back from Eiffel, and I think I came
out with a good strategy for this. However, a couple
of weeks ago I realized that this was working to good, and
that now I couldn't see why I was using accessors instead
of slot-value for normal slots. I had never thought
about the `unexport' issue (there was no unexport in
Eiffel 2, after all).

In Eiffel, a function can refer to the internal features
of `Current' (self), without concern for exporting issues
(but if you access the feature via `.', you're considered
a client, and should have the proper rights).
In C++, a member or friend function can also `look inside'.

So, given a class C, we can define functions in the 
associated package C as C's friends. (Of course, a 
package D of a subclass D of C, has to be considered
a 'subpackage' of C, and the appropriate package
engineering performed).


A function which is not a friend of a class is not
allowed to perform slot-value on the class (any
evaluation of slot-value on the class in a non-friend
package is wrong).

A friend defined for C accessing slot S, should
have no problem accessing S in D, even if D is deleted
(thanks to the MOP) or renamed. A method for
SLOT-VALUE-USING-CLASS with specializers D and C::S
takes care of the mapping.

For every slot that you want exported, you need an
accessor. Exporting the symbol is orthogonal to the
exporting concept here. A feature being private in D
means that 

  a) an accessor function is not defined
or
  b) the accessor function is specialized
     to raise an error when applied to an instance of
     D (of course, this can be `re-exported' for 
     instances of a subclass of D).

As this is an important issue, I have crossposted this
quite heavily in order to get good ideas from smart people
in other net.hoods .

-- 
Fernando D. Mato Mira                           
Computer Graphics Lab                           
Swiss Federal Institute of Technology (EPFL)    Phone    : +41 (21) 693 - 5248
CH-1015 Lausanne                                FAX      : +41 (21) 693 - 5328
Switzerland                                     E-mail   : ········@epfl.ch