Re: Information hiding in CLOS?
- From: "Kaz Kylheku" <kkylheku@xxxxxxxxx>
- Date: 19 Oct 2006 10:21:43 -0700
sankymoron@xxxxxxxxx wrote:
So I come from a {..} background, and I've been reading up details of
CLOS. (must say it is awesome!).
One thing I could not find: In C++ Class definitions, we have public,
protected and private members.
This is an artifact of C++ classes having a double role. C++ classes
not only define the structure of run-time objects, but they also serve
as namespaces.
If you declare some x in a class C, then that x is a member of the C
namespace, i.e. it is the symbol C::x. This is a separate relationship
from x being a member of the class C. The latter semantic relationship
can exist independently of namespace containment.
For instance, why couldn't some A::b be a member of class C?
// fictitious example
class C {
typedef int A::b;
double A::z;
};
C++ has namespaces, but it hadn't always. If C++ had had them from the
early beginnings, perhaps classes would work differently today.
If classes didn't serve as namespaces, then it would have to be
namespaces which control access. And namespaces would no longer be
declaration regions, either. You would need a way of declaring that
some name X exists in this namspace, under such and such protection,
without actually declaring that name to have any semantics in the
programming language, because you would actually want to use that name
elsewhere for naming something. A ``symbol'' keyword might do the
trick:
namespace A {
private:
symbol X; // X exists in namespace and is private
public:
symbol Y;
symbol C;
}
Now you can continue withour imaginary flavor of C++ and use the
symbols:
int A::X = 3; // error, we are not in A namespace, and X is private
namespace A {
int A::X; // ok, we are in A.
int X; // unqualified X means A::X
}
class A::C { // C is public, so this is okay
int A::X; // error, we are not in A
void A::Y(); // Good, Y is public in A.
};
namespace A {
class C { // really A::C
int X; // Okay: this is A::X and we are in A
};
}
A::C c; // OK, we are not in A, but C is public.
c.X = 3; // error, no symbol X known in this scope.
c.A::X = 3; // Error, A::X is private
c.A::Y(); // Okay, since Y is public.
using A::Y; // import it
c.Y(); // use unqualified
This gives a kind of gist of how Lisp packages work, or how a very
similar concept might work in C++ syntax. Symbols are entered into
packages, and packages control symbol visibility (external or
internal). When the reader reads Lisp expressions, it always has a
current package context. Unqualified names are resolved with respect to
that current package. Qualified names are used to refer out of the
package.
You can use symbols from any package to name an entity and its
components. A class can be X::Y, with a slot being Z::W. Some method
M::N can be specialized to take a parameter of that class.
In Common Lisp, you can import names that live in a package into
another package.
The internal symbols can always be accessed with a double colon. If S
is internal to package P, then P::S can always refer to it, but P:S is
erroneous. If S is an external symbol in package P, then either P:S or
P::S can refer to it.
Use internal symbols to name things that are intended to be private,
and don't document those things for others to use. Of course, people
can still discover those things and use the double colon to use your
symbols anyway.
.
- References:
- Information hiding in CLOS?
- From: sankymoron
- Information hiding in CLOS?
- Prev by Date: Re: How can I build a dynamic website better with CLISP?
- Next by Date: Re: Environment "Aha"
- Previous by thread: Re: Information hiding in CLOS?
- Index(es):
Relevant Pages
|