Nestmates
Eric Lippert
ericlippert at gmail.com
Thu Jan 28 16:25:46 UTC 2016
Good day all,
> It seems reasonable that other languages would similarly want to define
an encapsulation domain that spans multiple VM classes (like, perhaps, C#'s
"partial class" construct).
I just want to clarify what partial classes do in C#. All portions of a
partial class in C# combine to form a single CLR class *at compile time*.
Partial classes are entirely a syntactic sugar for "I want to express the
logic of this class in two or more physically distinct files". The compiler
simply gathers them up, verifies that they do not grossly contradict each
other (by, say, inheriting from two different base classes), pastes them
together, and compiles them as though they were lexically a single class.
The motivation for partial classes was automatic code generation scenarios
where the IDE generates boilerplate code based on the state of the forms
designer; we do not wish the user to edit this code, but we also want them
to be able to add their own methods to the class without having to create a
derived class. So the machine-generated code goes in one portion -- with a
big comment saying you can read this code but please don't edit it -- and
the user-generated code goes in another, and the compiler takes care of
putting them together later.
So these are entirely a compile-time construct. There's no way to "add on"
to a partial class after compilation. The accessibility rules in partial
classes are exactly the same as though the class text was lexically all
together, as you'd expect.
There is a feature of C# that does allow extension of an accessibility
domain across compilations in an unusual way though.
In C# the accessibility modifiers are private, public, protected and
internal; internal means accessibility is granted within the same
*assembly*. C# has an "internals become visible" feature that allows you to
mark assembly Alpha as "my internals should be treated as public when the
assembly doing the asking is assembly Bravo". This is typically used for
testing scenarios where Bravo contains the unit tests for Alpha's internal
implementation details. It is a feature which gives rise to odd corner
cases, and some members of the C# design team are *not big fans*, to say
the least.
Cheers,
Eric
On Thu, Jan 21, 2016 at 5:25 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> Certainly we would like it to be useful beyond Java. Extrapolating from
> Java's situation, we've told the users that a "class" is everything between
> the outermost { ... }, and defined encapsulation rules based on this notion
> of class boundary. For various expedient reasons, at various points in
> Java's evolution (inner classes, lambda proxies, specialization) we've
> chosen to implement a single "user class" as multiple "VM classes",
> necessitating hacks and backdoors to preserve the user's expectations (and
> sometimes failing.) It seems reasonable that other languages would
> similarly want to define an encapsulation domain that spans multiple VM
> classes (like, perhaps, C#'s "partial class" construct). The nestmate
> concept is motivated by the problem we have *now*, but we'd like it to be
> useful beyond the immediate situation. On the other hand, we don't want to
> extrapolate wildly to what some language might want, or define something
> that is so complicated that we can't predict the security consequences.
>
> More inline.
>
> On 1/21/2016 6:10 PM, Vlad Ureche wrote:
>
>> Thank you for sharing these insights Brian!
>>
>> I think I understand the problem and the solution, but let me ask three
>> questions to make sure I understood well:
>>
>> 1) The NestTop attribute must contain the child classes (except
>> specializations and lambdas, which are added dynamically), right? Is this
>> for security, so another class could not pose as a NestChild to access
>> private data? What about allowing the NestTop attribute to say "anyone who
>> wants to nest here is welcome to do so"?
>>
>
> Security is indeed the motivation. It's the VM's job to enforce what
> private means; while there are plenty of ways to dodge this (and we'd like
> to close some of them down), accessibility control is part of the integrity
> model of the JVM. In order to inject yourself into another classes' nest,
> you'd need to modify that classes classfile -- in which case you can do
> anything you want with their data anyway (just make all the fields
> public.) The two attributes form a handshake.
>
> An easy way to say "anyone who wants to nest here may do so" is to make
> your state public, and possibly enforce language-level access control to
> make sure that they've actually requested such nesting.
>
> 2) Why did you choose to have symmetry and transitivity? I understand that
>> having an equivalence relation allows partitioning, but it's not clear to
>> me why partitioning is important in this case.
>>
>
> Simplicity. By having a partitioning, and a distinguished canonical
> member, it is very easy to determine what access control credentials are in
> play. It also goes back to the user model -- there is some unit of
> encapsulation that the language defines (class) that determines what
> "private" means.
>
> We could do something fancy with friends, and transitive friends, and
> marriage brokers, and itinerant priests selling indulgences, but it doesn't
> seem that the return on complexity there is worth it.
>
> 3) Why is the NestChild limited to a single top class?
>>
>
> Again, because the encapsulation model is supposed to be simple. Just as
> each line of code belongs to only one source file, each bytecode belongs to
> one nest. \\
>
> Perhaps another way to think of it is: its the simplest thing we could
> think of that solves our current problem and yet seems not completely
> ad-hoc :)
>
> These questions stem from pondering whether we can use the nestmates
>> mechanism to implement Scala's enclosing-entity-private access specifiers
>> (e.g. a variable in class List can be private[scala.collection.List] or
>> private[scala.collection] or private[scala])... Still, I don't think this
>> can be done at the granularity required by Scala, so we'll continue to have
>> name-mangled accessors where necessary :(
>>
>
> Right. These are overlapping scopes of accessibility, more like "virtual
> packages" than "nestmates". This seems like a slightly different problem.
>
>
>
More information about the valhalla-spec-observers
mailing list