ceylon/ceylon-spec — Issue #56: Alternate visibility model
Author: gavinking
Created: 2011-11-21 04:34:59+00:00
State: open
Labels: request for feedback

So I think it's fair to observe that the response to our visibility model has been a bit mixed. Now, I'm sure we could put a lot of that down to the fact that it's something different, and whenever something is different to what people are used to, some people are going to dislike it until they get used to it.

Still, as much as I think this is a much better model than what Java has, there's a couple of things that even I don't love about it. Having to add `shared` annotations everywhere in simple examples really does get irritating. And it's especially difficult to justify the need for `shared` when the declaration and caller are defined in the same file. Finally, since we say you can't do type inference for `shared` declarations, there are actually some cases where type inference is disallowed that would actually be perfectly acceptable from the compiler's point of view.

So here's an alternative visibility model, that builds on some discussions we've had previously. I'm not so much arguing for this model, as putting it out there to see if you guys bite.

The rules would be:

1. Any declaration is visible to all other code in the same compilation unit (file).
2. A declaration annotated `shared` is visible to all other code in the same module.
3. A declaration annotated `shared` contained in a shared package is visible to other modules.

Among the interesting consequences of this design:

* In simple examples, where all code can go into one compilation unit, there is no need for any `shared` annotation at all. Furthermore, very few explicit type annotations would be required.
* There is no support for package-private visibility (but we've really struggled to find practical use cases for this).
* Moving a declaration from one file to another within the same package can break code (though we have a couple of quick fixes in the IDE that can pretty quickly take care of this).
* There is a "scope" (of visibility) that is not a namespace, nor even part of the block structure of the language. A compilation unit is not a namespace.
* I would have to rethink the whole brain-hurty issue of the relationship between visibility and refinement. I'm pretty sure I managed to prove to myself that the current model doesn't have any pathological cases (where refining a member would reduce its visibility), but I think that only worked out because every visibility scope is also a block in the block structure of the language.

I find the last two points a bit difficult to swallow. If we required that all code in a package were defined in the same file, I would find this whole model *much* more natural.

Nevertheless, the truth is that I would simply *love* to be able to introduce the language with examples that don't have `shared` splattered all over them. And I also love how this model works so naturally with our type inference restrictions.

So, again, this is a request for community feedback. Note that we won't be making any changes to the current visibility model in M1, but we could consider changing the model in M2 or perhaps even in M3.