> On Apr 12, 2017, at 3:15 PM, Nevin Brackett-Rozinsky via swift-evolution > <[email protected]> wrote: > > In order to evaluate this proposal, I created a table of as many relevant > scenarios as I could think of, and listed how each of the proposed solutions > would work there. The four access level systems I compared are: > > No change: The existing Swift 3 status quo with “fileprivate” and “private”. > > SE–0159: Revert to the Swift 2 meaning of “private” (file visibility) and > eliminate scoped access altogether. > > SE–0169: Expand “private” to include the current type and all its extensions > in the same file. > > Rename: Change the spelling of “private” to “scoped”, and “fileprivate” to > “private”. > > I ended up with a list of eight scenarios to evaluate. These are: > > 1. “Simple file”, a single type with no extensions. > 2. “Extensions”, a single type and extensions thereof. > 3. “Sharing”, multiple types that need privileged access to each other. > 4. “Helper visible”, the interface of a helper (or nested) type for use > within the file. > 5. “Helper hidden”, the details of a helper type that should not be visible > to other types. > 6. “Invariants”, the details of a type that should only be touched by > dedicated methods. > 7. “Multi-type”, multiple types that should not have privileged access to > each other. > 8. “Multi-type + ext”, multiple types that should not have privileged access > to each other, and extensions thereof. > > The entries in the table have seven possible values: > > private: The “private” keyword works. > > fileprivate: The “fileprivate” keyword works. > > scoped: The “scoped” keyword works. > > private x2: The “private” keyword works if the types are put into separate > files. > > fileprivate x2: The “fileprivate” keyword works if the types are put into > separate files. > > helper type: The goal can only be achieved by creating a helper type. > > no hiding: The specified items cannot be hidden from the rest of the file. > > Here is the completed and color-coded table (I hope it displays properly in > this email): > > > > No change > SE–0159 > SE–0169 > Rename > Simple file > private > private > private > private > Extensions > fileprivate > private > private > private > Sharing > fileprivate > private > fileprivate > private > Helper visible > fileprivate > private > fileprivate > private > Helper hidden > private > no hiding > private > scoped > Invariants > private > no hiding > helper type > scoped > Multi-type > private > private x2 > private > scoped > Multi-type + ext > fileprivate x2 > private x2 > private > private x2 > > > Analysis > > Some people have said on-list that they view cross-type sharing as an > anti-pattern. If that is true, then we can simply ignore the “Sharing” row > because it would not be worth optimizing for. This hardly changes the table > though, as that row is identical to the “Helper visible” row below it. > > Regarding the “Invariants” row, note that a helper type can be used for this > purpose under “No change” and “Rename” just as well as under “SE–0169”. The > difference is that SE-0169 provides no other way to hide invariants from the > rest of the type, whereas the other two have an access level suited to the > purpose. Similarly, the multi-type rows can be satisfied by separate files > regardless of which access system is in place. > > If a person takes the view that things in the same file should naturally have > access to one another, then the bottom four rows of the table can be ignored. > Such a person might have the mantra, “Only put things together if they belong > together”, and they would ask, “What else is in the file that you are trying > to hide from?” > > For someone whose primary use-case is to put one type in a file and build it > up through extensions, the “Extension” row is of greatest concern. To them, > any of SE–0159, SE–0169, or renaming would let them use “private” instead of > “fileprivate” everywhere. > > As a final remark, each of the four options has one notable benefit and one > notable drawback, not all of which are apparent from the above table: > > No change > Benefit: No change to the language. > Drawback: Must use “fileprivate” to build up a type through extensions. > > SE–0159 > Benefit: Simplifies the access control model. > Drawback: Cannot protect invariants within a file. > > SE–0169 > Benefit: Cross-type sharing is clearly marked. > Drawback: Must use a helper type to protect invariants within a file.
FWIW, a secondary drawback to SE-0169 is that the protection afforded by this helper type is permeable - the helper type can be extended anywhere inside the file. It is more than SE-0159 but not as strong a guarantee as either no change or rename. Extensions to the helper type will stand out much more clearly than inadvertent use of a `private` member under SE-0159 but readers still need to know they don’t exist or look for them to be sure. > > Rename > Benefit: No change to semantics. > Drawback: Two separate keywords are changed. > > • • • > > And now, having said all that, I need to go take a nap! > > Once everything has percolated, I’ll come back to write a review of the > current proposal. > > Nevin > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
