Static Types vs Dynamic Capabilities (was: a few thoughts)
Mark S. Miller
Mon, 17 Jul 2000 12:53:27 -0700
At 12:20 PM 7/17/00 , Karp, Alan wrote:
>Perhaps another way to implement thinnings is to reverse the parentage. In
>other words, the thick interface is the superclass and the thin one the
>subclass. You can prevent a holder of a reference to a thin object from
>invoking a method only in the thick interface by overriding the excluded
>methods. That's what I did for my homogeneous collections; overriding the
>add(Object) method thinned the interface to allow only add(Thimble). Now,
>there's no problem with casts. Since an object carries its type with it,
>you can never escape from its facet.
This would work sort of (see below), in that it would have the correct
dynamic security properties. But it would render the static type system
useless as an aid to static reasoning about what operations will succeed at
runtime. Statically, the type system will tell you that thick-only
operations would succeed when invoked on a variable declared of thin type.
The failure would now only happen at runtime.
One might argue that Java cast-failure, such as my first p2 to p3 example,
also causes a failure only at runtime. But this failure happens at cast
time, which is often usefully prior to operation-invocation time.
And what's the advantage over the proxy-restricted-forwarding technique I
explained? It seems only that it uses inheritance rather than delegation.
Because it uses inheritance, there's only one object reference to give out,
because there's only one object to designate. This means that the technique
is useless for creating both thick and thin facets to the same object.
Rather, one can only use it to reuse code to create an object of less
authority than the code was originally designed to instantiate. Though it
succeeds at this, it hides the authority by inheritance-overriding rather
than by encapsulating a capability representing the greater hidden
authority. This would require us to expand our conceptual toolset for
reasoning about authority.
This is a good example of the more general tension between object-oriented
inheritance and capability security. This tension is resolved by turning
patterns of inheritance into patterns of delegation
http://www.erights.org/elang/blocks/inheritance.html . Were we to apply
this transformation to your suggestion, we'd get the proxy-forwarding
technique I explained earlier. With a clever implementation (much more
clever than any anticipated in the near future!) these patterns of
delegation need not be more expensive than inheritance.