Holy mackerel, these replies are getting long.

On Thu, Jul 3, 2014 at 12:32 PM, Jonathan S. Shapiro <[email protected]> wrote:
> Ironically, I used to take the view that the object was the state, and there
> might be many organizations of behavior acting on that state. That's the
> view in which downcast and upcast don't change the object.

Now _that's_ a wrong way of thinking. Specifically that whether an
object includes its behavior would have anything to do with the
semantics of cast. Maybe we're using "behavior" differently. To me,
behavior is just method implementations.

> I held this view
> because in KeyKOS/EROS/Coyotos you can end up with multiple capabilities to
> the same process that have very different effects on the "object" presented
> by that process.

So I would call these different facets, views, or wrappers, but the
object is the process, and it includes its behavior.

> From the human standpoint, the thing that you can mentally
> "point" to is the blob of state, so it's conversationally natural to think
> of that as the object. The definition "object = state + behavior" is kind of
> unnatural conversationally when you start having interfaces.

I agree that the intuitive use case of the term "object" is when
there's some state that forms the center of the thing. (The thing you
"point" at.) But any behavior that cannot be separated from the
concrete representation of the state is behavior that must also be
considered part of the encapsulated object. After that, any additional
operations using only the abstract interface are not part of the
object. (Or at least they ideally wouldn't be.)

> Incidentally: KeyKOS/EROS/Coyotos is an example of a system that has objects
> without inheritance. Capabilities conceptually denote interfaces. In EROS
> and Coyotos, interface signatures are defined by IDL, and interfaces can be
> extend (be derived from) other interfaces.

Cool. I'm no fan of inheritance. People say null pointers were a
billion-dollar mistake, but at least they're sensible. Implementation
inheritance is just a crappier version of tried and true reuse
techniques that already existed.

I haven't read many technical details of capability OSes, but I tend
to like the OO/component middleware version of OO better than any
actual OO programming language I've seen, and capability IPC seems
similar. (But better, I'm sure.) I think the fact that messages can
leave the process forces designers to really think about objects the
right way, and not as some collection of language implementation
techniques. (If you have I problem with that, please forget I said it.
I don't want this thread to fork even more sections.)

> At least in the OS context, I haven't found that interface inheritance has
> introduced any problems. It's hard to know if this is because interface and
> implementation are so strictly separated, or merely because we didn't
> proceed far enough to hit problems.

I think you'd be fine. Interface inheritance (bad name, what inherits
what? "extend" is still OK) is really just a form of subtyping, which
makes perfect sense.

>> Let me summarize how I'm thinking about Java...
>
> OK. What you are saying makes sense to me now, but I find the terminology
> very confusing. Partly because I don't see this as a static/dynamic
> relationship. I see it as a type/inhabitant relationship. But even more
> because the word "dynamic" has all sorts of associations when we are talking
> about types, and those associations seem unrelated to what you are saying.

It can't be helped, the world just hasn't chosen enough buzzwords. ;)
I've been trying to learn some advanced math recently. Mathematicians
are really good at coming up with lots and lots of distinct nonsense
words for the many subtly-different things they study. It makes it
seem terribly technical, but it might actually be helping in the long
run.

> I don't have a better term to suggest. I'm just trying to articulate why
> this is likely to continue to throw me off so that we can both be aware of
> the possibility of disconnect.

Well, I just made up the therm on the fly to try to communicate. Pick
anything that works better for you, as long as it doesn't just confuse
me instead.

> Huh? I want some of what you're smoking.
>
> Oh. Perhaps what you are saying is that all of the operations are actually
> there, on the object, to be called (the dynamic interface), but that some of
> them may not be reachable through a particular interface or at some given
> superclass type. Is that what you are saying?

Yes.

> If that's so, then no, I think that you really have this mixed up. It's
> exactly the ability to present a restricted subset of function that
> constitutes the ability to capture different authorities.
>
> If the language imposes promiscuous downcast or existential elim, then what
> you say is of course correct in the end. I prefer to think of that as a
> fundamental flaw in the language design rather than a property of cast.

I'm being descriptive, rather than prescriptive, in how I'm thinking
about Java. The merits and demerits of Java's object model is a whole
'nother discussion.

> I think we're on the same page here, and we're debating where to attach this
> concept of authority in our respective lexicons of language concepts.

Or at least we're discussing two possibilities. I already said I like
what you came up with for BitC.

>> Wrappers, on the other hand, give you a different object, probably
>> with a different dynamic interface, so wrapping and unwrapping is
>> central to controlling authority.
>
> Yes and no. Yes to what you say about wrappers, but more generally, any
> operation that gets you from one "perspective" on an object to a different
> "perspective" having a different API is central to controlling authority.

That sounds right, provided the API in question is a full account of
the permissions granted by the object reference. I might be overusing
the term "wrapper".

> The notable exception being when the effect is a strict reduction on the
> original authority.

How is strictly reducing permissions not controlling permissions? Is
this some technical sense of "control" that I didn't pick up on?

>> I see how what I said was ambiguous. English is lousy at this.
>
> Well, yeah. But if it were easy, anyone could do it, right? :-)

I think it could be easier than it is if there were better, more
standard terms for these ideas. But it still wouldn't be easy.

> I meant only that the Java notion of "object" is
> not exactly "object = state + behavior".

Can you explain what you mean by that?

>> > But from the purist perspective object = state+behavior, downcast gets
>> > you a
>> > new object because it gets you new behavior.
>>
>> No, the behavior of an object is accessed through its dynamic
>> interface, which isn't affected by casts.
>
> I actually do think you have this wrong. Yes, at bottom,
> there is a complete set of possible object behaviors (what you seem to mean
> by dynamic interface).

OK, by "behavior" you seem to mean implemented public methods, which
in general is different from implemented methods that access the
concrete state representation. For instance, private methods can
account for the majority of an object's behavior. I'll try to play
along.

> But the ones that I can actually exercise are
> constrained by the static type through which I invoke.

But they're not! You can downcast or reflect. That's exactly why my
way is in fact the right way to think, if you're stuck with Java.

> Actually, the right term here is "permission", not "authority". Authority is
> the transitive reflexive closure of reachable permission.

Oops, I think you're right. Though it technically depends on whether
downcast then call should be considered as two steps. I vote no, since
the downcast doesn't require permission. I guess I drank the kool-aid
that it's not terribly important how many steps are involved. If you
can do it, you can do it.

>> Yeah, I heard. It's a clever implementation technique, but we should
>> be going on the abstraction that the language provides, not how it's
>> implemented.
>
> Perhaps. But if so, we should be going on the abstraction that the language
> provides, not to be confused with what the manual documents. Java interface
> objects really are wrappers

It sounds like you're saying Java remains incorrectly implemented on
this issue, according to the manual. I don't recall the manual or spec
saying anything about interfaces being separate wrapper objects. The
wrappers are semantically invisible within the language.

> Yes. But in this case the implementation details make it clear that they are
> wrappers. There are other possible implementations, but they are
> semantically equivalent to the separate VTable implementation. Which is to
> say that all of them are semantically equivalent to wrappers.

Yes, all of them are semantically equivalent to wrappers which
*deliberately have the same object id as the original object*. If that
is not a sign that the wrappers are meant to be ignored, I don't know
what is.
So, for contrived example, you could implement all dispatch with
reflection. Then you have no vtables or wrappers. Reference types are
just erased.

>> I guess the question then is: Is BitC going to have a
>> notion of dynamic interface distinct from the static type?
>
> No. BitC will not.

So why are we still talking about this? :) Is it 'cause arguing about
our area of interest is so much fun? Nah, can't be.

> Ah! (Light dawns). The dynamic interface you speak of is completely exposed
> by run-time introspection! I finally think I see why this is important in
> your mind.

Yup. Great! How much of your reply above does this change? :)

> Add promiscuous introspection to the list of things that is profoundly wrong
> in Java and .NET.

Well I think they made an honest attempt to make "private" private,
just with the "pragmatic compromise" that non-sandboxed reflection
could work around it. This turned out to be a terrible decision,
because the sandbox was garbage, private methods show up in the class
metadata, and because then you can't aggressively optimize private
method calls. (Actually, maybe that's not true, if reflection does
more work to figure out the optimized calling protocol.) You probably
know even more things wrong with private-breaking "promiscuous"
reflection. I agree that it's totally fucked up.

But I thought if you get rid of promiscuous reflection, then "private"
does provide abstract data type-style encapsulation. I realize I'm
being slightly hypocritical to ignore promiscuous reflection, but not
all reflection, in my analysis of the language. The secret is I think
that the language as I imagine it would actually be a defensible
design, though not ideal. I mean, if you get technical, JNI breaks
_everything_. There are certain features one doesn't use without a
hazmat suit.

> It's okay to have parts of the surface syntax that are
> helpful "sugar", like private/protected/public. The problem is that it's too
> easy to confuse those for having some real protective or encapsulative
> value.

Maybe you're right. I repeat that I am OK with what you came up with
for BitC. Your solution is actually sensible under both
interpretations, since your interfaces _are_ distinguishable wrapper
objects.
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to