Split Capabilities: Making Capabilities Scale
Karp, Alan
alan_karp@hp.com
Tue, 25 Jul 2000 16:22:16 -0700
As I said in my first reply to Mark, if I know the full interface, I don't
have a problem. What you describe is exactly this situation. The "object"
is the state plus the behavior represented by the union of all the facets,
not just the facet I hold. Mark stated quite explicitly that "no automatic
awareness is provided". It is this lack of awareness that prevents my
thinking of the facet as an object. If von Braun is unaware of a facet
allowing increment, and he treats the facet as an object, he must assume
that any increase in the counter is due to a fault in the counter mechanism.
_________________________
Alan Karp
Decision Technology Department
Hewlett-Packard Laboratories MS 1U-2
1501 Page Mill Road
Palo Alto, CA 94304
(650) 857-3967, fax (650) 857-6278
> -----Original Message-----
> From: Dan Bornstein [mailto:danfuzz@milk.com]
> Sent: Tuesday, July 25, 2000 3:33 PM
> To: Karp, Alan
> Cc: e-lang@eros-os.org
> Subject: RE: Split Capabilities: Making Capabilities Scale
>
>
> [Apologies in advance: I wrote this note in bits and pieces during a
> somewhat busy workday. I hope it's at least somewhat coherent.]
>
> MarkM writes:
> >Were this done is a Java-like statically typed language,
> both increment
> >and decrement facets would be seen as being of type
> >
> > public interface {
> > void do();
> > }
> >
> >with no further type information available.
>
> Alan Karp writes:
> >Seems like an odd programming model where I say "do your
> thing whatever
> >that may be". What would Werner von Braun say during a
> countdown, do() or
> >decrement()? What would he say if he saw the count increase
> as he tried to
> >count down?
>
> I wrote:
> >The thing to keep in mind is that, in any useful system,
> this object would
> >have been received in an already-rich context. In von Braun's case,
> >presumably he got it by calling the
> getCountdownDecrementer() method on a
> >particular missileControl object, the same object he uses as
> the target of
> >repeated calls to getCountdownValue(). If he saw the count
> go up, he might
> >choose to call missileControl.abort() and then do further
> research after
> >things had settled down.
>
> Alan Karp writes:
> >My point exactly. Had he known that the object supports
> increment, he'd
> >know that the countdown was on hold. Seeing only the facet
> and thinking
> >it's an object, he can only assume there is an error that
> forces him to
> >abort the launch. Strict object encapsulation says that the
> object state
> >can only be changed through the interface. Since he sees no
> increment
> >method, he must assume that the object has a flaw.
>
> It seems that we're seeing the same situation and drawing opposite
> conclusions.
>
> My point is that if the object is in fact a "facet" of a system that
> supports increment, von Braun *would indeed* know that
> because he got the
> object in a context where he knows what all is available. And if the
> missileControl semantics included having a launch be "on
> hold" then von
> Braun would also know about that, and he would have been coded as
> appropriate for that situation.
>
> The thing about checking the counter was me attempting to describe a
> possible sanity check or assert. I was starting from the
> assumption that
> the missileControl had the three methods (get countdown, decrement
> countdown, and increment countdown). von Braun *knows* the
> counter isn't
> supposed to increment during a countdown, but just to be safe
> he checks his
> assertion using the provided facility. If there's a problem,
> he aborts the
> mission. If the count increment weren't available at all in the first
> place, then this assertion check would probably be
> unnecessary. And, if
> that were the case, von Braun would know, from context, that it indeed
> wasn't a part of the missileControl interface.
>
> I wrote:
> >The way out of the mess is to assume that one is starting
> from a context
> >of objects that one knows certain properties of, such as
> whether they are
> >trustworthy. Assuming von Braun has reason to trust the
> missileControl
> >object in question, then he would transitively trust the result from
> >calling missileControl.getCountdownDecrementer(), whether or not he's
> >using a strongly-typed class-based system.
>
> Alan Karp writes:
> >This reasoning is exactly why I don't feel comfortable
> treating a facet as
> >an object. The facet hides part of the interface and tells
> me only some of
> >the properties.
>
> I don't get your reasoning. Yes, the facet hides part of the
> interface and
> tells you only some of the properties. But what's wrong with
> that? (Even
> stronger: that's the point exactly!) One never really has an object in
> isolation. Or, if one only has an object in isolation,
> there's a reason one
> got to be in that situation.
>
> Let's look inside von Braun's programming (extreme psuedocode and code
> personification alert). First, I'll assume that
> missileControl in fact has
> these methods:
>
> object missileControl {
> fun :any counterDecrementer();
> fun :any counterIncrementer();
> fun :any counterGetter();
> fun :any aborter();
> fun :any launcher();
> }
>
> All of these methods are meant to return a(n anonymous)
> function to do the
> job the name implies (e.g., the result of calling aborter()
> is a function
> that, when called, aborts the launch).
>
> Let's say von Braun himself is just responsible for performing the
> countdown and signalling either to launch or abort, and he is handed a
> missileControl object to do his work. von Braun assumes that
> he isn't the
> only object with access to the missileControl and wants to
> faithfully send
> an abort signal if he notices that anything is amiss (in
> particular, if the
> counter ever increases). von Braun might be written as this:
>
> # von Braun works by spawining a launchControl process and
> # a countDown process.
> fun vonBraun (missileControl) {
> spawn launchControl(missileControl.counterGetter(),
> missileControl.launcher(),
> missileControl.aborter());
> spawn countDown(missileControl.counterDecrementer(),
> missileControl.counterGetter(),
> missileControl.aborter());
> }
>
> # launchControl can get a count, issue a launch, and
> issue an abort.
> # it repeatedly gets the count and issues a launch if the count is
> # zero, or issues an abort if the count ever increases.
> it exits after
> # sending either a launch or abort signal.
> fun launchControl (counterGetter, launcher, aborter) {
> var oldCount = counterGetter();
> repeat forever {
> var newCount = counterGetter();
> if (newCount > oldCount) {
> aborter();
> break;
> }
> if (newCount == 0) {
> launcher();
> break;
> }
> oldCount = newCount;
> }
> }
>
> # countDown can decrement a count, get a count, and issue
> an abort.
> # it issues one decrement per second and checks to see if
> the count
> # is as expected. if not, it issues an abort. it exits
> when the count
> # is zero or immediately after sending an abort signal.
> fun countDown (counterDecrementer, counterGetter, aborter) {
> var oldCount = counterGetter();
> repeat forever {
> sleep 1 second;
> counterDecrementer();
> var newCount = counterGetter();
> if (newCount != (oldCount - 1)) {
> aborter();
> break;
> }
> if (newCount == 0) break;
> oldCount = newCount;
> }
> }
>
> So, what von Braun has done is broken the problem into two
> pieces. Neither
> piece requires the full missileControl capability, and so he
> doesn't pass
> that to the sub-processes. He only passes them the
> capabilities they need,
> which in this case are all facets of the same missileControl
> object. This
> makes it easier for him to verify the correctness of his subprocesses.
> Also, since he's the one that instantiates the subprocesses,
> he knows that
> the only capabilities they have are the ones he gave them, and so they
> *cannot* misbehave by using the counterIncrementer().
> Furthermore, even
> though von Braun himself can send a launch(), he knows that of the two
> subprocesses, only launchControl() may do that; countDown()
> can't because
> he didn't pass it the capability to do so.
>
> By the same token, the thing that instantiated von Braun himself (the
> government?) knows that, since von Braun was only given a particular
> missileControl object (and nothing more), he also cannot misbehave in
> certain ways. For example, it isn't necessary to check that
> whether von
> Braun is taking money from Fort Knox, since he was never passed the
> fortKnox capability. However, since they chose to give him the full
> missileControl capability, it might be worth their while to
> do additional
> sanity checks on his actions, just in case, during code
> review, they missed
> a place where he calls or leaks a reference to
> missileControl.counterIncrementer().
>
> None of the above requires that any of the objects themselves
> be labelled
> explicitly with "what they are." von Braun, by his nature, trusts the
> missileControl he is given. The aborter that von Braun passes to his
> subprocesses is an aborter merely because it was the result of calling
> missileControl.aborter() on a missileControl object that von
> Braun trusts.
> The aborter that the launchControl subprocess receives is trusted
> implicitly, because the basis of launchControl's operation is
> in receiving
> three trustworthy objects that interact in a particularly
> well-defined way.
> Type annotations might help debug the system, but having code
> that passed
> type inspection is not an assurance of its correctness.
>
> -dan
>