Side-effect free containers for E
Tyler Close
tjclose@yahoo.com
Tue, 15 Aug 2000 15:29:47 -0400
Markm wrote:
> I think this is a truly excellent point. Yes, indeed, this
> represents a
> second very different instance in which I made the same mistake.
> Congratulations! I'd say you've internalized the principle
> of least
> authority better than I.
Well, I had some excellent teachers. Thank you.
> This is also along the lines of a design rule Dean has
> advocated (and
> presumably practiced) for Joule code: No subtypes that add
> authority.
> Echoing Ken's last message, I think this issue is the first
> showing a
> tension between good capability protocol design practices,
> and good object
> protocol design practices -- assuming the object designer isn't
> concerned with security per se. Subtyping, including
> subtyping that adds
> authority, is part of how object programmers achieve lots
> of pleasant
> polymorphism without having to say alot.
I think there is a significant design methodology issue here that,
strangely enough, coincides with the recent discussion of facets (ie:
the whole counter object thread).
Object programmers typically create authority aggregates using
inheritance (either through interfaces or all-out implementation
inheritance, including multiple inheritance). This technique results
in the use of protection proxies to pare down the aggregate's
interface to that represented by a particular super-class. The use of
proxies introduces a number of complexities, some of which were
discussed in the "counter object" thread, some of which are being
discussed in this thread.
In the case of containers, it is possible to dodge the issue entirely
by simplifying the type hierarchy down to one. However, in general,
saying "No subtypes that add authority" is a prohibition that offers
no solution. It is only an excellent guidepost and a clear warning
flag.
It seems so many of these issues are derived from the debate of
delegation vs. inheritance.
The other way to create authority aggregates is through delegation. In
this design, the 'composite' object would contain references to the
'component' objects. The composite object is not polymorphic with any
component. Clients that operate on a subset of the composite's
authority are not given a protection proxy for the composite, but are
given the actual component object (or an object that pretends to be
the component object).
Client code expecting operands of a particular type can still operate
on composites, but rather than indirectly, through polymorphism,
directly, on the component. This preserves the best part of what the
inheritance solution offered.
The delegation solution also offers an important new advantage to the
capability programmer. It allows you to leverage the type system to
catch authority overflows. I believe this will be a driving force in
the design of capability programs that is not present in object
programming.
As Markm noted, object programmers typically design their types to
permit authority overflows. As we're discussing, this is bad for
security, and as we've discussed before, it leads to the creation of
deep and complicated class taxonomies (as the designer attempts to
make everything polymorphic with everything).
Pictorially, an object design typically looks like a pyramid, with
objects getting ever fatter as you descend the type hierarchy. I
believe a good capability design should look like a collection of
approximately uniformly small marbles with different shapes and sizes
of boxes to put them in. The difference is that some object designers
get their marbles confused with their boxes.
> Of course, for E, the existence of such a tension is
> especially unfortunate,
> as E is trying to gently seduce object programmers into
> being capability
> programmers. E's strategy depends on enabling new E
> programmers (but old
> object programmers) to build simple things quickly without
> having to learn
> very much. So I think E must evaluate separately each case
> where these
> principles conflict.
I think E's lexical scoping style will mean that inheritance style
aggregates will rarely be a problem. I think we will mainly have to be
careful when importing Java code into E, or reimplementing Java
designs in E. So far, we certainly have some good empirical evidence
to suggest that this is the case. Marcs wrote EDesk in E without
having this problem and Markm couldn't add containers to E without
having this problem.
Amazing how language changes your thinking.
Tyler
_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com