Re: Visibility

Daniel Bonniot <[email protected]> Wed, 23 Mar 2005 13:08:12 +0100
Newsgroups gmane.comp.lang.nice.general
Message-ID <[email protected]>
Rohan Hart wrote:
> On Sun, 20 Mar 2005, Daniel Bonniot said:
>  > It's not implemented yet, but the plan is to use JVM visibility as
>  > much as possible.
> 
> Surely JVM visibility must support *all* of the Nice visibility
> semantics?  Otherwise there's the danger of Java code subverting,
> deliberately or not, Nice visibility.

Even Java rules cannot all be enforced by JVM visibility. For instance, try 
accessing a private member from an inner class. javac creates an accessor 
method with package visibility, which opens the possibility for such subversion.

Such rules enforced at the source level only are still useful, not from a 
security point of view but from a software engineering one.

>  > With package (default) and public, the mapping is obvious. Private
>  > would likely be more difficult to use, unless we change the way code
>  > is compiled (which could be done is the long run).
> 
> Given that Nice methods are associated with packages rather than
> classes what meaning are you attributing to "private"?  Private makes
> more sense for fields but then there'd be no method which could access
> them.

private would restrict visibility to a single "module". (Typically a module is 
a source file, but that can be left to the implementation to decide, for 
instance in an IDE that would not create files at all, or if we decide to 
allow several modules explicitely in the same file)

At the bytecode level, this could not be enforced right now. However, I think 
it should not be hard to create one bytecode class per module (instead of per 
package as now) which would allow to enforce private methods. If a module 
contains only one class, then we could use that class to put the methods of 
the module, which would also allow to enforce private fields. (we could even 
reject modules that define several classes with private fields, to guarantee 
we always enforce privacy at the bytecode level)

As an aside, I now think it makes sense to support private methods. In the 
simplest version, private methods would be allowed as long as they have a 
single, default implementation. This already allows "helper functions", which 
is quite useful in practice. I believe it's possible to allow more forms of 
private methods. What is surely required is the default implementation, to 
guarantee coverage. Avoiding ambiguities in extending packages is the trick. I 
think that ambiguities could only happen if some implementation of the method 
dispatches on an interface. If that's correct, we could simply disallow that 
for private methods. (The exact same reasoning applies to non-public methods)



>  >> local: can not be specialised outside the defining package even if it
>  >> can be called in that context - a modifier to the above visibilities
>  >> and not the default
> 
>  > Is this about methods?
> 
> Yes.  I see it as corresponding somewhat to Java's "final", so there's
> likely a mixture of good and bad points around providing it.  I
> mentioned it mostly because it can be enforced with JVM visibilities,
> by stopping Java code from sub-classing the method's dispatcher class.

What do you mean by "the method's dispatcher class"?

Would it make sense to use the "final" keyword for this? "local" confuses me 
at first, because it seems to be a synonym of "private". I understand such 
methods would not be final in the Java sense, but close (the set of 
implementation is final at the package level).


>  > It's possibly problematic to limit implementation of methods: what
>  > happens if another package defines a new class for which no
>  > implementation of the method is applicable?
> 
> Then that class doesn't and can't conform to the method contract and
> thus is invalid.  Harsh and paranoid but then marking some method as
> "local" is all about paranoia.

OK, only it's possible that when defining that class the method is not known, 
so the class cannot be rejected then:


package p1;
interface I {}

package p2; import p1;
public local void foo(I);

package p3; import p1;
public class A implements I {}
// cannot fail here, foo is not known

package p4; import p2; import p3;
// foo(A) is not implemented.
// cannot implement it because foo is "local"


However, the above restrictions for private methods could also be used to 
reject foo (missing the default implementation).


Could you give some motivations why "local" would be useful? Concrete examples?



>  > It could seem to be sufficient to require that non-public methods
>  > have a default implementation (since they are not public,
>  > ambiguities cannot be created in other packages). But actually, you
>  > can create an ambiguity by declaring a new class that implements
>  > two interfaces.
> 
> Sorry, lost me there.  What aspect of (multiple-inheritance based?)
> ambiguity here affects the visibility?

Here is the potential problem:

package p1;
interface I {}
interface I1 extends I {}
interface I2 extends I {}

private String foo(I);
foo(I1 i1) = ...;
foo(I2 i2) = ...;

package p2; import p1;
class A implements I1,I2 {}

// ambiguity about foo(new A())

If foo was public, you could solve the ambiguity in p2. With the restriction 
of no dispatch on interfaces for non-public methods, this case is ruled out.


>  > The reverse situation seems to be useful as well: do not allow some
>  > method to be called outside the package, but still leave open its
>  > implementation for such situations.
> 
> Useful but not the default?

If the restriction is correct, then I don't think it would be useful anymore. 
And the situation would be more satisfactory.


Daniel



-------------------------------------------------------
This SF.net email is sponsored by: 2005 Windows Mobile Application Contest
Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones
for the chance to win $25,000 and application distribution. Enter today at
http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click