The arguments for the revert are in the proposal and in the discussions in 
this thread.

What is in the proposal and this thread are a set of opinions, e.g.

* "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,”
* "it is extremely common to use several extensions within a file.”
* “[existing regime] encourages overuse of scoped access control”
* “[fileprivate is the] more reasonable default”

I am asking for the arguments or evidence that led you or others to these 
opinions.  I understand that you and others believe them, but you understand 
that they are now a matter of debate. We are not going to reach any mutual 
understanding just asserting things we believe.  The underlying evidence is 
what would be necessary to convince others to our point of view.  I am trying 
to ascertain what that evidence is.

> It has pointed quite a few times by core team members that comparison to 
> languages is not a very strong arguments, 

The context here is that you presented an argument that Swift’s “private” was 
confusing to users of other languages:

> In most languages, that keyword is “private” so its valid to say that 
> newcomers to the language will “default” to using that one. 

If you no longer think that argument is strong because it relies on a 
comparison to other languages, then we agree :-)  But in that case we lose an 
argument for this proposal.  The reason we are talking about other languages is 
because that was an argument advanced to support the proposal.

> Some people used the for(;;) loop, the ++ operator, var parameters.

In those cases, there was extensive discussion of how to achieve the things 
people were achieving with those features with alternative patterns. var 
parameters for example have a 1LOC workaround to achieve the previous 
semantics, ++ had two characters, for(;;) was slightly trickier but we had a 
clear concept of the scope of the impact. So far as I’m aware, the only 
suggestion to people who currently use a scoped access modifier is to stop 
having their problems. So the circumstances of earlier removals and this one 
are very different.

> • either a programmer ... will use private as often as possible
> • or a programmer will … use fileprivate all the time 
There is also the possibility that a programmer considers which modifier is 
appropriate for the code they are writing.  You "argue that... is very rare” 
but I still am not sure what this argument is or what led you or others to this 
conclusion.

On March 21, 2017 at 1:41:48 PM, David Hart ([email protected]) wrote:





Sent from my iPhone
On 21 Mar 2017, at 16:57, Drew Crawford <[email protected]> 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.

"A lot of talk" is not the evidence supporting the proposal: it's just a 
warning that something may be very controversial among the community. The 
arguments for the revert are in the proposal and in the discussions in this 
thread.

> 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:

A user wants to restrict visibility (e.g. they are dissatisfied with “internal”)
The user *chooses* private because of familiarity from another language
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.

It has pointed quite a few times by core team members that comparison to 
languages is not a very strong arguments, especially when Swift does things 
differently for a good reason. I can't stop from quoting Xiaodi from a month 
back:

«The beauty of Swift 2's access modifiers was that they were based around files 
and modules, explicitly rejecting types and scopes as units for determining 
visibility.» -- Xiaodi

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.

The point is that keeping both private and fileprivate feels like an 
un-necessary complication:

• either a programmer falls on your side of the fence and will use private as 
often as possible and relegate to fileprivate when the design leaves no other 
choice. At that point it feels like a language wart.
• or a programmer will fall on my side of the fence and use fileprivate all the 
time and the language feels like it has an unnecessary access modifier.

I'd argue that the cases when a programmer will use both meaningfully is very 
rare. As a consequence, we should try to only keep one. Removing fileprivate is 
a no-go with extensions so that leaves us with removing private.

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.

I can generate statistics from my projects if you want. But it's unnecessary: I 
haven't used private once since it's introduction in Swift 3. I don't see the 
advantages it brings worth the trouble.
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.

The migrator migrated to fileprivate everywhere, not private, disagreeing with 
your use of fileprivate.

> 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.

Some people used the for(;;) loop, the ++ operator, var parameters. Many other 
features were removed from Swift to simplify he language, make it more 
consistent. Those are worthwhile goals. Yes, we are past Swift 3 now, but that 
doesn't mean we shouldn't be able to propose a few rare breaking proposals. The 
implementation of access modifiers came so late in the Swift 3 timeframe that 
we had little time to play around with them before Swift 3 was released. Now 
that we have, we have a short window of time to fix mistakes that were made. 
I'm just arguing that the proposal was one of those mistakes. But you have a 
right to disagree.
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.

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 ([email protected]) 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 
<[email protected]> 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 ([email protected]) 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 [email protected] 
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
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

Reply via email to