TWiki . Dev . VisibilityModifiers

What should be the exact semantics of the VisibilityModifiers?

Can VisibilityModifiers added to method declarations or method implementations or both?

How do VisibilityModifiers affect where you can implement and/or call methods?

I have thought about this but I didn't get consistent and usefull semantics. The only easy ones are the global constants.

Anyone some good ideas?

-- ArjanB - 09 May 2003

It's also easy for functions (unless we have FunctionsReplacedByMultiMethods, in which case the question disappears).

For methods, I think that visibility only makes sense to method declaration. It should restrict the places from where you can call the method. I don't think that we can/should restrict the places you can implement the method, because I believe that in some situations you would need to implement a method where it is not accessible.

Similarly for classes, visibility should not restrict implementing a method for that class. I can see too usages for non-public classes. One is to make the constructor restricted, which means you cannot instanciate them outside the scope. The other is that you cannot use them in types. The first one is surely needed (singleton pattern). I'm not sure about the second. A possibility is that both would be restricted. I think the second one is too restrictive to be useful in practise.

- DanielBonniot - 10 May 2003

The simplest solution is to make VisibilityModifiers only affect the places where you can call a method/constructor. I think there should also be a way to restrict the places where you can implement a method. Implementing a simple form of the VisibilityModifiers first and using them will give more insight in what kind of additional restrictions are needed.

-- ArjanB - 03 Jun 2003

Agreed. I thought that a good way to start implementing this would be to develop an independant library for managing symbols with visibility properties. That would help keeping the complexity out of the compiler, and thinking abstractly. It should probably be implemented in Nice, but keep in mind might be called by some Java code. Anybody feels like working on this?

One feature that I find useful is when "invisible" symbols are not completely ignored, but the system can tell you "foo is defined in package bar, but it is not public". Something to keep in mind is that we might want to have different visibility for the same symbol in different contexts (ex: a field that is public when reading it, but private when writing it). That could come in a second phase, though.

-- DanielBonniot - 04 Jun 2003

In InnerClasses, I mentioned that I use inner classes in Java to emulate Eiffel's selective export language feature. ArjanB? mentioned a "proposal is to give sourcefile access to things with the private modifier." I'm not sure how this works with methods of a class being defined in multiple files, multiple classes methods' being defined in one file, etc., so some of my concerns below may be irrelevent.

I think making all the classes in a single source file the equivalent of friends would be a mistake. It removes nearly all the benefit of visibility modifiers for classes inside one source file, which would end up encouraging a more Java-like one class per file. It makes the most common case difficult in favour of making the less common easy (if not too easy.)

It would also be far coarser grained than an Eiffel-like selective export, becoming all-or-nothing. You could not restrict access to a subset of methods, but would have to either give access to everything or everyone access. For example, you want to give class B access to method Z of class A. To achieve this with the friend-like proposal, you either give class B access to everything of class A, or give all classes access to method Z. Neither choice is ideal. With selective export, you could just list class B in the export list for method Z, instead of specifying public or private.

Further, it makes specialization difficult. By specifically restricting to classes within the same source file it prevents subclasses defined elsewhere (which is how package, friend, and inner-classes work, I don't know about the Nice proposal) from achieving the same degree of flexibility. With selective export, you could create a class C subclassed from class B, and it would still have access to method Z. With package/friend/inner classes, you'd have to actually define class C in the same source file as class B, which is impractical and often impossible (e.g., class B is in a library.)

Selective export is a wonderfully usefull feature, but is all about finesse and fine control. Emulating it with package/friend/etc. is destructive overkill. I'd love to see Nice gain this advantage over Java. I'm not sure how they would interact with multi-methods though.

I must also say that I find it a little unsettling that units of storage, the source file, are being given semantic meaning in the language. While certainly convenient to the language designer, I think it makes the language a bit inflexible.

-- Vulcannis - 28 Aug 2003

The main problem of visibility in nice are multimethods, they do not belong to a class so defining usefull semantics is difficult. I haven't seen any other language with multimethods that has visibility restriction. For acces related to subclasses as protected in java I see no way to give them clean semantics. Besides restricting where a method can be called we need a way to restrict where method implementations can be added. Visibility remains an open issue for now, probably it will be implemented in many small steps to find out a good balance between control and flexibility. I will take a look at eiffel for hopefully some good ideas.

-- ArjanB - 28 Aug 2003

I'm going to consider only class or package member (field and method) access from functionals (multimethods or functions) and ignore class visibility. Here's a diagram of Java's visibility rules for accessing. At each functional implementation location relative to the member we're accessing, all members with any visibility below, to the right, equal to the table position are accessible:

Location same class subtype of class anywhere
same file private    
same package     (package)
anywhere   protected public

From the above we get two chains of inclusion: public > package > private, and public > protected > private, where > means “is more accessible than.” It's possible to apply the exact same visibility rules to Nice. Using these rules would be a good place to start.

The rules for accessing private members could be relaxed. Private members could be permitted to be accessed by any functional, as long as they appear in the same file. Since Nice functionals aren't very strongly linked to classes, I favor this approach. The table is displayed below. At each location relative to the member we're accessing, all members with any visibility below, to the right, equal to to the table position are accessible:

Location same class subtype of class anywhere
same file     private/protected
same package     (package)
anywhere   protected public

Discarding protected would simplify the above table: private would mean “this file only,” and package and public are self-evident (protected is not currently even a recognized keyword in 0.9.1). However some design patterns, e.g. Template Method, rely on protected. I think protected can be implemented for multimethods: a given method implentation should have access to protected members of any objects that are passed to it via dispatch.

It should definitely be possible to specify different visibilities for reading and writing fields. Trouble is, there are a lot of combinations of visibility, even with the restriction that field set must be less visible than field get. Something like public(read) private(write) int x; or public(get) private(set) float y are very clear, but verbose. Hyphenated words might work: public-private, public-read (package write), and private-write (package read) cover all the cases that don't involve protected.

A side note: it's also possible to provide support for rare cases where accessing a hidden member may be desirable. AspectJ provides the privileged keyword for this ( It applies to an entire aspect, and grants that aspect the ability access to all members. If privileged is deemed useful for inclusion in Nice, I think it should apply at the functional implementation point instead of the class level, but the idea is still the same.

-- JohnBMesserly - 29 Aug 2003

Nice seems to have more than the usual design constraints, because of the expectation that Java classes will be extensively reused in Nice code. In the MethcallIntermediateExample, the java class in JavaToggleExample was written with the expectation that subclasses could access protected fields - that is not the case in Nice 0.9.2

The handling of protected java fields/methods is a known problem that needs to be fixed. -- ArjanB

-- IsaacGouy - 17 Sep 2003

I agree with Daniel that for methods, visibility only makes sense for the method declarations and should affect (only) the places you can call the method. But, I agree with Arjan that there should be a way to prevent specializations of a method from outside the package it is defined in.

It makes sense that a class's visibility would affect the ability to implement a method for that class. For example, if a class C is private to a package a.b.c, it should not be possible to define a multimethod that has an a.b.c.C argument or return type outside of package a.b.c. Similarly, it should not be possible to define a public method M in package a.b.c that is declared to accept parameters of type a.b.c.X or returns type a.b.c.X.

The visibility of a class's constructor should be at least as restrictive as the class's visibility. For example, it doesn't make sense to have a public constructor for a package-private class. However, it does make sense to have a package-private constructor for a public class. It might be useful to have protected for constructors--A protected constructor of class X can only be used by a constructor for a subclass of X. Then you could also have package protected which would allow use of the constructor by a subclass of X as well as by any code defined in the same package as X.

Beyond constructors, I don't think any modifier giving subclasses special privileges is very useful. Presumably, it would only apply to the classes' initializer and the default value expression for its fields.

I agree with Vulcannis when he says that it is "unsettling that units of storage, the source file, are being given semantic meaning in the language." But at the same time it does seem useful to have source-file level visibility as long as a single package can be spread across multiple source files. Perhaps a good way of handling this would be to have a package visibility modifier instead of private. A symbol (class, method, field, value) without a visibility modifier would be visibile only within the source file it is declared in. To grant access to other source files in the package, it must be marked with a package modifier. To grant access to other packages, it must be marked with a public modifier. Then you don't need a private to mean "this source file only" at all.

It seems like selective export like in Eiffel seems like it can only apply at the package level since methods are seperate from classes. E.g. package A could export symbols f, A, B.c to packages B and C. I am not sure how useful it is.

One important aspect is what the default visibilities should be. My preference is to make everything source-file-private by default. My second preference is to require a visibility modifier for every package-level construct.

-- BrianSmith - 04 Feb 2004

----- Revision r1.13 - 04 Feb 2004 - 03:02 GMT - BrianSmith
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.