[swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

Ross O'Brien narrativium+swift at gmail.com
Tue Mar 21 11:31:33 CDT 2017


   - What is your evaluation of the proposal?

In general: against.
Scope-based access is useful and should not be removed.
The fileprivate keyword is long and awkward to say, but unambiguous in
purpose. 'Private' is ambiguous, referring to scope-based access inside a
scope but file-based access outside a scope; this is the more complex term.

I would be in favour of a modified Alternative #3: assigning one keyword to
file-based access and one keyword to scope-based access. However, as
discussed at length during SE-0025, neither level is intuitively the
correct choice to be 'private'.

I would also be in favour of Matthew Johnson's proposal for un-complecting
access from capability - the proposed syntax would address this problem,
though the proposed access-alias feature intended to ensure code is not
broken by its change would not address this problem.


   - Is the problem being addressed significant enough to warrant a change
   to Swift?

A change is required, but not significantly enough to apply the 'solution'
proposed.


   - Does this proposal fit well with the feel and direction of Swift?

No.


   - If you have used other languages or libraries with a similar feature,
   how do you feel that this proposal compares to those?

This proposal removes a useful feature.


   - How much effort did you put into your review? A glance, a quick
   reading, or an in-depth study?

Quick reading.

On Tue, Mar 21, 2017 at 4:12 PM, Matthew Johnson via swift-evolution <
swift-evolution at swift.org> wrote:

>
> On Mar 21, 2017, at 10:57 AM, Drew Crawford via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
>
> > I’m not arguing that it is less or more than a majority. I’m just saying
> that we’ve seen a lot of talk against the original change.
>
> This proposal asks us to balance the convenience of one group
> (extension-writers) against the existence of another (scoped-access
> users).  To do that, we need a clear idea of the composition of both groups.
>
> “A lot of talk” is not the evidentiary standard to remove a feature.  It
> was not good enough when we introduced the feature, that required argument
> and clear use-cases.
>
> > By default, I did not mean the syntactic default of the language but the
> access modifier users will use “by default” when trying to restrict
> visibility. In most languages, that keyword is “private” so its valid to
> say that newcomers to the language will “default” to using that one.
>
> Apologies, but I do not understand the argument:
>
>    1. A user wants to restrict visibility (e.g. they are dissatisfied
>    with “internal”)
>    2. The user *chooses* private because of familiarity from another
>    language
>    3. The user is then surprised that their choice of private indeed
>    restricted the visibility, thus achieving their goal?
>
> What language does the user come from in which “private” is file-visible?
> It isn’t Java, C++, or PHP.  C#’s “partial” is the closest I can think of,
> and it isn’t at all close.
>
> A user who wants a middle-ground visibility would “default” to
> “protected”, “friend”, “partial”, or similar.  After that does not compile,
> they will use google to find a middle-road visibility keyword, for which
> the only candidate is “fileprivate”.  But they will not choose “private”,
> it’s just not a reasonable expectation of what the keyword means to a new
> Swift developer.
>
> The popularity of private “as a default” is simply because many users
> prefer to hide their implementation details as a matter of routine code
> hygiene.  Redefining private in order to thwart their code hygiene goal
> seems extreme.
>
> I agree with several here (as I did in SE-0025) that our access modifiers
> are not well-named.  However, that’s not the proposal in front of us.
>
> > My own statistics in my projects show the contrary. At best, this shows
> how divisive this feature is.
>
> This *may* show that, if contrary statistics were presented, but that
> hasn’t occurred.
>
>
>    - In old code, statistics could be biased by the migrator having
>    replaced all previous instances of private by fileprivate.
>
> If the migrator migrated code to private, and it *worked* (e.g. did not
> introduce visibility errors) this is not bias, this is a correct use of the
> feature.
>
> > I'm just arguing that the additional scope-based access modifier does
> not provide enough differentiation to be worth that complexity.
>
> The only argument I have seen so far around “complexity” boils down to:
> “some people do not use it”.  But some people *do* use it, and anyway if we
> are going to remove all the features “not enough people” use then we are in
> for a ride.
>
> Swift 3 shipped, so what we are discussing now is yanking a keyword
> without replacement.  There is code written that uses private to enforce
> its threading or security invariants.  There is code written that uses
> private in order to shadow another declaration.   There is code that will
> not compile after migration. We need more than a vague fear of complexity
> generally to throw a brick through all those windows.  That brick will
> introduce quite a bit of complexity itself.
>
> +1.  On one side we have a vague notion of “complexity” which doesn’t
> appear to amount to much more than a statement of opinion that the
> granularity isn’t useful.  On the other side we have people who find
> legitimate value in the feature for important and clearly articulated
> purposes.  This seems to me to be a solid demonstration that the feature
> *is* useful.
>
> Compiler verification of invariant-preserving encapsulation is important.
> It is not trivial.  It is not something to be written off lightly because
> “you’re only protecting yourself from yourself”.  People make very similar
> arguments against static typing outside of the Swift community but most of
> us here see value in static types.  Frankly, I’m surprised that so many
> don’t see more value in compiler verified encapsulation.  Is it as
> important as a robust static type system?  No.  But that doesn’t make it
> unimportant.
>
> Concerning the one-class-per-file argument, I would suggest this
> counter-argument: when working in large projects, I believe it's a good
> thing if the language encourages (forces is too strong a word for my taste)
> a one class per file structure, it's good practice.
>
>
> The form of the argument is invalid.  Suppose I argued: "it’s a good thing
> for the language to encourage one definition per class (no extensions),
> it’s good practice.  So we do not need fileprivate.”  That would be very
> silly (although it has already been advanced as a straw-man position
> elsewhere in this thread). The argument that we do not need private because
> nobody should put multiple classes in a file is equally silly. There are
> reasons to do so, in fact one motivation was given in SE-0025:
>
> > Putting related APIs and/or related implementations in the same file
> helps ensure consistency and reduces the time to find a particular API or
> implementation.
>
>
> These concerns are not resolved by arguments of the form “just don’t do
> that”.
>
> I empathize with the Swift2 programmer who got through two releases
> without a scoped access modifier and is annoyed by change.  However,
> removing the feature now is more change, not less, so it makes their
> problem worse, not better.
>
>
> On March 21, 2017 at 2:17:40 AM, David Hart (david at hartbit.com) wrote:
>
> Perhaps it was a mistake, but I purposefully did not go into too much
> detail in the proposal because I think this debate is purely a question of
> philosophy on Swift and its language features. I did not want to add
> un-necessary bloat that would have added little rationalisation. Let me try
> to explain the holes in the proposal by answering your review:
>
> On 21 Mar 2017, at 02:26, Drew Crawford via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I disagree quite strongly with the proposal.
>
> First, the document draws conclusions without apparent supporting
> evidence, e.g.
>
> > Since the release of Swift 3, the access level change of SE–0025 was met
> with dissatisfaction by a substantial proportion of the general Swift
> community. Those changes can be viewed as actively harmful, the new
> requirement for syntax/API changes.
>
>
>    - What is “dissatisfaction by a substantial proportion of the general
>    Swift community”? How was this measured/determined?
>
> It’s not feasible to measure precisely the feeling of a whole community.
> But we get a feeling for it by following the mailing-list, by talking to
> colleagues, by reading twitter, etc… And it think we all agree that the
> debate is highly divisive and that a “substantial proportion” of the
> community was dissatisfied: I’m not arguing that it is less or more than a
> majority. I’m just saying that we’ve seen a lot of talk against the
> original change.
>
>
>    - What was done to control for the population happy with SE-0025 who
>    would e.g. not be likely to take up pitchforks?
>
> That’s why its important we have this debate now.
>
>
>    - Who argues these changes are “actively harmful” and where were they
>    during SE-0025?
>
> The proposal makes the argument that the changes are actively harmful.
> It’s now up to debate. By the way, even if several people (including me)
> were already against this proposal during the review, I don’t see why
> anybody would not have the right to change his mind, especially after
> several months of production usage and argue differently now.
>
> > subtly encourages overuse of scoped access control and discourages the
> more reasonable default
>
>
>    - Who claims that scoped access is “overused” and what is their
>    argument for doing so?
>    - Why is “fileprivate” the “more reasonable default”? In fact neither
>    fileprivate **nor** private are default (reasonable or not!). Internal
>    is the default. Nor does this proposal suggest we change that. So this
>    seems a very strange statement.
>
> By default, I did not mean the syntactic default of the language but the
> access modifier users will use “by default” when trying to restrict
> visibility. In most languages, that keyword is “private” so its valid to
> say that newcomers to the language will “default” to using that one. If the
> proposal is accepted, file-scoped private will regain that status.
>
> > But is that distinction between private and fileprivate actively used by
> the larger community of Swift developers?
>
> Yes. To cite some evidence, here are codebases I actively maintain:
>
> | codebase                                               | private # |
> fileprivate # | ratio |
>
> |--------------------------------------------------------|--
> ---------|---------------|-------|
>
> | "M" (proprietary)                                      | 486       | 249
>           | 2x    |
>
> | "N"(proprietary)                                       | 179       | 59
>            | 3x    |
>
> | NaOH https://code.sealedabstract.com/drewcrawford/NaOH | 15        | 1
>             | 15x   |
>
> | atbuild https://github.com/AnarchyTools/atbuild        | 54        | 5
>             | 11x   |
>
> So from my chair, not only is the distinction useful, but scoped access
> control (private) is overwhelmingly (2-15x) more useful than fileprivate.
>
> My own statistics in my projects show the contrary. At best, this shows
> how divisive this feature is. During the discussion of this proposal, it
> was argued that making decisions based upon project statistics would be
> dangerous:
>
>
>    - In old code, statistics could be biased by the migrator having
>    replaced all previous instances of private by fileprivate.
>    - In new code, satistics could be biased by people using private
>    because of it being the “soft-default”, regardless of proper semantics.
>
> > And if it were used pervasively, would it be worth the cognitive load
> and complexity of keeping two very similar access levels in the language?
> This proposal argues that answer to both questions is no
>
> This proposal does not make any later argument about “cognitive load” or
> “complexity” I can identify.  Did the proposal get truncated?
>
> Sorry if I did not state it explicitly, but I see any feature/keyword
> added to the language as “additional complexity”. And that complexity is
> completely worth it when the feature adds significant expressivity. I'm
> just arguing that the additional scope-based access modifier does not
> provide enough differentiation to be worth that complexity.
>
> What is stated (without evidence) is that "it is extremely common to use
> several extensions within a file” and that use of “private” is annoying in
> that case.  I now extend the above table
>
> | codebase                                               | private # |
> fileprivate # | ratio | # of extensions (>=3 extensions in file) |
>
> |--------------------------------------------------------|--
> ---------|---------------|-------|--------------------------
> ----------------|
>
> | "M" (proprietary)                                      | 486       | 249
>           | 2x    | 48                                       |
>
> | "N"(proprietary)                                       | 179       | 59
>            | 3x    | 84                                       |
>
> | NaOH https://code.sealedabstract.com/drewcrawford/NaOH | 15        | 1
>             | 15x   | 3                                        |
>
> | atbuild https://github.com/AnarchyTools/atbuild        | 54        | 5
>             | 11x   | 6                                        |
>
> in order to demonstrate in my corner of Swift this is not “extremely
> common”, and is actually less popular than language features the proposal
> alleges aren’t used.
>
> My point here is that ***different people in different corners of the
> community program Swift differently and use different styles***.  I can
> definitely empathize with folks like the author who use extensions to group
> functions and are annoyed that their favorite visibility modifier grew four
> extra characters.  Perhaps we can come up with a keyword that is more
> succint.
>
> I agree that different people in different corners use different styles.
> But you could use that argument to validate many features which would make
> a group of users happy; but all those feature together would just add bloat
> to the language. Swift has been known to be a very opinionated language, to
> keep the language simple yet expressive.
>
> However, that is no reason to take away features from working codebases.
> A scoped access modifier is perhaps my favorite feature in Swift 3.  Let’s
> not throw stuff away because it adds extra characters to one programming
> style.
>
> Finally, SE-0025 establishes clear motivation for the scoped access
> modifier:
>
> > Currently, the only reliable way to hide implementation details of a
> class is to put the code in a separate file and mark it as private. This is
> not ideal for the following reasons:
>
> > It is not clear whether the implementation details are meant to be
> completely hidden or can be shared with some related code without the
> danger of misusing the APIs marked as private. If a file already has
> multiple classes, it is not clear if a particular API is meant to be hidden
> completely or can be shared with the other classes.
>
> > It forces a one class per file structure, which is very limiting.
> Putting related APIs and/or related implementations in the same file helps
> ensure consistency and reduces the time to find a particular API or
> implementation. This does not mean that the classes in the same file need
> to share otherwise hidden APIs, but there is no way to express such
> sharability with the current access levels.
>
> As far as I can see, the proposal does not actually address or acknowledge
> these problems at all, but cheerfully returns us to them.  It would be a
> mistake to deprecate this feature without examining at all why we
> introduced it.  And realistically we need new solutions to those problems
> before removing the existing one.
>
> Drew
>
> On March 20, 2017 at 6:54:55 PM, Douglas Gregor (dgregor at apple.com) wrote:
>
> Hello Swift community,
>
> The review of SE–0159 “Fix Private Access Levels” begins now and runs
> through March 27, 2017. The proposal is available here:
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0159-fix-private-access-levels.md Reviews are an important part
> of the Swift evolution process. All reviews should be sent to the
> swift-evolution mailing list at
>
> https://lists.swift.org/mailman/listinfo/swift-evolution or, if you would
> like to keep your feedback private, directly to the review manager. When
> replying, please try to keep the proposal link at the top of the message:
>
> Proposal link:
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0159-fix-private-access-levels.md Reply text Other replies What
> goes into a review?
>
> The goal of the review process is to improve the proposal under review
> through constructive criticism and, eventually, determine the direction of
> Swift. When writing your review, here are some questions you might want to
> answer in your review:
>
> What is your evaluation of the proposal? Is the problem being addressed
> significant enough to warrant a change to Swift? Does this proposal fit
> well with the feel and direction of Swift? If you have used other languages
> or libraries with a similar feature, how do you feel that this proposal
> compares to those? How much effort did you put into your review? A glance,
> a quick reading, or an in-depth study? More information about the Swift
> evolution process is available at
>
> https://github.com/apple/swift-evolution/blob/master/process.md Thank you,
>
> -Doug
>
> Review Manager
> ------------------------------
>
> swift-evolution-announce mailing list swift-evolution-announce at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170321/74dd5d54/attachment.html>


More information about the swift-evolution mailing list