Sent from my iPad

> On Mar 21, 2017, at 7:40 PM, Xiaodi Wu via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> On Tue, Mar 21, 2017 at 6:44 PM, Drew Crawford <d...@sealedabstract.com> 
>> wrote:
>>>> I am confused by this response. An argument in _support_ of new `private` 
>>>> was that it is more in line with expectations of users coming from other 
>>>> languages. In other some cases, such an argument might have its place. 
>>>> However, as others have pointed out on this list, those other languages 
>>>> don't have facilities like Swift's extensions, and therefore it was not a 
>>>> very strong argument for new `private` to say that it better aligns with 
>>>> user expectations coming from other languages.
>>> 
>>> The underlying issue here (which I have now identified, thanks!) is what 
>>> motivates the use of extensions.  That question predates proposals, but the 
>>> Swift book provides the following motivation, which I have numbered for 
>>> ease of reference:
>>> 
>>> 1. Extensions add new functionality to an existing class, structure, 
>>> enumeration, or protocol type. 
>>> 2. This includes the ability to extend types for which you do not have 
>>> access to the original source code (known as retroactive modeling). 
>>> 
>>> 3. Extensions are similar to categories in Objective-C.
>>> 
>> 
>> It seems to me this motivation contemplates use “at some distance”, that is 
>> we intend to create some semantically meaningful separation between the 
>> declaration and the extension(s).  If we did not we could use MARK or some 
>> other comment-based scheme to organize our class.
>> 
>> 2 is explicitly at great distance, so we know the distance motivation is 
>> well within scope.  1 refers to “an existing” type which implies a certain 
>> level of functionality in the unextended type, and not merely a partial 
>> implementation in the unextended type.  The record on 3 is more mixed (ObjC 
>> programmers do occasionally use categories “closely-held” to group a few 
>> methods together).  However ObjC also has the “distance” tradition: 
>> categories cannot introduce new storage even when this is technically 
>> trivial (within the same compilation unit for example), and this tradition 
>> was continued under Swift with the new ABI.
>> 
>> What I am suggesting is that the primary design purpose of an extension is 
>> to create semantic distance between a declaration and the functionality 
>> being added.
> 
> I'm not sure it is necessary for extensions to have a "primary design 
> purpose." They serve many purposes. One use I have for them is as follows:
> 
> ```
> struct A {
>   // Stuff here constitutes the "raison d'etre" for A.
> }
> 
> extension A : B {
>   // In the course of implementing `A`, I have discovered that
>   // `A` can fulfill the semantic guarantees of `B`, and in fact
>   // fulfills most of them already.
>   //
>   // So, I conform to B, as in so doing there are some practical
>   // advantages, such as gaining some default implementations.
>   //
>   // But, to conform, I may need to implement some methods
>   // not really essential for a functional `A`, but required nonetheless
>   // to conform to `B`.
>   //
>   // I implement them here in an extension; in so doing, I express
>   // the idea that I have, after implementing `A`, discovered its
>   // conformance to `B`, and I am here supplying the remaining
>   // implementations necessary for that conformance.
>   //
>   // That is, if `B` did not exist, neither would these functions here.
>   // But there may be some requirements of `B` that would be
>   // implemented in `A` whether or not `B` exists.
>   // Those are implemented above, in `struct A { ... }`.
> }
> ```
> 
> I find this to be an eloquent way to separate concerns. It is a common 
> pattern encouraged by code I admire written by others more skilled than me in 
> Swift.
> 
>> A mechanism to hide variables from extensions is something that *furthers* 
>> this design goal of extensions, rather than contradicts it.
> 
> This, I suppose, is an argument for you to take up with Charles.
>  
>> I understand that some people use extensions as sort of an imitation 
>> “partial class” but they simply aren’t (no storage) and we should introduce 
>> a new feature if we want to have them.
>> 
>>> A core team member (I'm blanking on who) has pointed out that, in the end, 
>>> the only necessary access modifiers are public and not public (spelled 
>>> "internal" in Swift).
>> 
>> 
>> It is not clear to me how this squares with the decision in SE-0025 that 
>> other access modifiers were necessary.  Can you clarify?
> 
> Why do you think SE-0025 decided that other access modifiers are necessary? 
> It merely decided that having four was deemed, on balance, superior to having 
> three. But the minimum number of access modifiers is, by definition, two. In 
> the case of Swift those essentially have to be at the module boundary. 
> Anything more finely diced than that and you are balancing expressivity and 
> complexity. I would not be opposed, incidentally, to stripping back access 
> modifiers to two: `internal` (or maybe eliminate that explicit annotation 
> altogether) and `public`.
> 
>>> When new `private` and `fileprivate` were shipped, there were numerous 
>>> questions asked by users on forums such as Stack Overflow
>> 
>> 
>> And before they were shipped, there were people asking for a scoped modifier.
> 
> No, I'm not talking about "asking for"; I'm talking about "asking"--as in, "I 
> don't get it, please explain." The point is that the distinction between 
> `private` and `fileprivate` is not an intuitive one.
>  
>> And when we change them again, what questions will that generate?  So I 
>> don’t see what we are accomplishing with this line of inquiry.
>> 
>>> You see the new access modifiers described, for example, as something that 
>>> "take[s] some getting used to." Rather damning as a euphemism, don't you 
>>> think? 
>> 
>> Not at all.  We could describe strong typing, or optionals, enums, pattern 
>> matching, etc., in this way.  ARC in particular is “difficult to teach” but 
>> we should not get rid of it, it solves a safety problem.  A scoped access 
>> modifier is similar.
>> 
> 
> Again, the argument is not that scoped access modifiers have _no_ merits or 
> that it solves _no_ problems; it is that its merits are greatly outweighed by 
> its drawbacks, or that the problems solved are not more pressing than the 
> problems introduced, which include problems in learning and teaching Swift.
> 
> Swift promises only one type of safety by default: memory safety. ("Swift is 
> a high-performance system programming language. It has a clean and modern 
> syntax, offers seamless access to existing C and Objective-C code and 
> frameworks, and is memory safe by default.")
> 
> Since ARC helps to deliver two indispensable promises ("seamless access 
> to...Objective-C" and "memory safe by default"), that weighs heavily in its 
> favor despite difficulty of learning and teaching. `fileprivate` is, I think 
> you'll agree, certainly not a clean and modern syntax, and its presence or 
> absence has little to do with the other tentpole promises of Swift.
> 
>>> When the Swift core team approved the proposal, they expressed the belief 
>>> that `fileprivate` would be rarely used. This has turned out plainly and 
>>> indisputably not to be true. It is clear that they expected Swift to have, 
>>> after SE-0025 (and before `open`), three commonly used access modifiers and 
>>> one vestigial one. Instead we have four/five commonly used access 
>>> modifiers. Thus, the complexity of the current system is _not_ what was 
>>> envisioned at the time of approval for SE-0025, and the resulting system 
>>> should be re-evaluated in light of this real-world data. 
>>> 
>> 
>> The only citation I can find on this topic is the cryptic “fileprivate is 
>> rarely needed” in the context of “rare enough to be explicit”.   I submit 
>> that according to previously-presented data, I do use it rarely, less often 
>> than the other modifiers, certainly in a manner consistent with being 
>> explicit.  I do not see how we jump from that fact pattern to “plainly and 
>> indisputably… _not_ what was envisioned at the time”.  It is not plain and I 
>> do dispute it.
>> 
> 
> *You* may indeed write in a style that uses it rarely. I think you see from 
> even this conversation that others do not code in such a style. There are 
> 183,000 results for `fileprivate` on Google, which is in the same ballpark as 
> results for `associatedtype`. Compare with 60,800 for `precedencegroup` and 
> 1430 for `ExpressibleByStringInterpolation`.
> 
>>> The code above should compile and does not.
>>> 
>> 
>> It is not clear to me how this is especially relevant.  The point of a 
>> scoped access modifier is to prevent programs from compiling when they 
>> should not.  Here is a program that does not compile when it should; that’s 
>> a bug, but it doesn’t go to whether the scoped people are caught with their 
>> pants down or working from bad safety assumptions.  It’s just a complier 
>> crasher.
>> 
> 
> It is relevant because this is not some corner case; it's not some fuzzed 
> nonsense like `{{<<var;;` that happens to crash the parser. It is a tentpole 
> feature of `private` proposed in SE-0025 that shipped broken in 3.0 and will 
> ship broken in 3.1. In other words, SE-0025 has not been completely 
> implemented, and if ABI stability is declared before it is fixed, it may not 
> even be completely implementable.
>  
>>> (a) even proponents of new `private` disagree on one of two key goals 
>>> stated for new `private`;
>>> 
>> 
>> I suspect that not everyone will agree on the three stated goals for 
>> extensions either, but I do not with to remove them.
>> 
> TSPL is not the document of record for goals for extensions, it's a 
> pedagogical tool. By contrast, SE-0025 is the document of record for goals 
> for the new `private`. They may not be *your* goals for `private`, but they 
> are *the Swift community's* goals for `private`, and they have not been met.
>> I wish to improve them, and a scoped access modifier is one of the tools we 
>> have to do that.
>> 
>>> As far as I can see, in that example, you can rename `private func prune` 
>>> to `private func _prune` and have no further problems. That is to say, the 
>>> workaround is a single character at each use site, which by your metric 
>>> makes this proposal half as onerous as removing `++`.
>> 
>> The problems are described in SE-0025:
>> 
>>> > Another, less reliable, way is to prefix APIs that are meant to be hidden 
>>> > with a _ or do something similar. That works, but it’s not enforced by 
>>> > the compiler, and those APIs show up in tools like code completion, so 
>>> > the programmer has to filter out the noise — although these tools could 
>>> > quite easily support hiding methods with the _ prefix standard. Also, 
>>> > there is a greater danger of using private APIs if they do something 
>>> > similar to public APIs but are somehow more optimized (because they make 
>>> > additional assumptions about the internal state).
>> 
>> In any case, this workaround is not “semantically equivalent” and so 
>> regardless of the number of characters it is different than ++ or var.
>> 
> I'm not sure how the quotation describes a semantic issue; it describes a 
> practical drawback with respect to code completion. And it's correct. Again, 
> I'm not saying that there are no merits to a scoped access level. I'm just 
> saying that a tidier code completion menu and not writing `_` aren't in 
> themselves compelling. The workaround after removal is totally transparent to 
> the end user, and all uses of a non-public API in the same file can be 
> trivially audited to prove that they aren't called at unintended places, so 
> I'm not sure why you think some bar of "semantic equivalence" needs to be met.

Uses in a single file at a single point in time can be audited trivially.  
Ensuring correct use  all (scope)private variables in all files of a large 
project over a span of years is not so trivial.  This kind of mistake can slip 
through code review even on diligent team.  The compiler guarantee has 
significant value in these contexts.

> 
>  
>>> On March 21, 2017 at 5:26:47 PM, Xiaodi Wu (xiaodi...@gmail.com) wrote:
>>> On Tue, Mar 21, 2017 at 3:59 PM, Drew Crawford via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>>>>  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.
>>>> 
>>> 
>>> I am confused by this response. An argument in _support_ of new `private` 
>>> was that it is more in line with expectations of users coming from other 
>>> languages. In other some cases, such an argument might have its place. 
>>> However, as others have pointed out on this list, those other languages 
>>> don't have facilities like Swift's extensions, and therefore it was not a 
>>> very strong argument for new `private` to say that it better aligns with 
>>> user expectations coming from other languages.
>>>  
>>>>> > 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.
>>> 
>>> You've given one example of code that takes advantage of new `private`. As 
>>> far as I can see, in that example, you can rename `private func prune` to 
>>> `private func _prune` and have no further problems. That is to say, the 
>>> workaround is a single character at each use site, which by your metric 
>>> makes this proposal half as onerous as removing `++`.
>>> 
>>>> 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.
>>>> 
>>> 
>>> I'm not enamored of the argumentation in the proposal set out above. But 
>>> since you are saying that you're not sure how anybody came to support this 
>>> proposal, here's how I arrived at supporting it:
>>> 
>>> A core team member (I'm blanking on who) has pointed out that, in the end, 
>>> the only necessary access modifiers are public and not public (spelled 
>>> "internal" in Swift). It has been my understanding that supporting all 
>>> possible ways of hiding a member from arbitrary other code within the same 
>>> module is a _non-goal_. There have been numerous attempts at designing 
>>> elaborate access modifier schemes that make this possible with friends, 
>>> protected, shared, what-have-you, and I try to bring up this point each 
>>> time.
>>> 
>>> Beyond the two absolutely essential access modifiers, anything else does 
>>> not add to safety as the term is understood in Swift, but rather improves 
>>> developer experience. But what is gained in terms of developer experience 
>>> with each additional access modifier (due to increased expressiveness) is 
>>> offset by what is lost due to complexity. So then the question is: what is 
>>> the ideal number of access modifiers? is it two? three? four? five? six? 
>>> eight? ten? twelve?
>>> 
>>> When new `private` and `fileprivate` were shipped, there were numerous 
>>> questions asked by users on forums such as Stack Overflow (easily googled; 
>>> just as a single example: 
>>> http://stackoverflow.com/questions/39027250/what-is-a-good-example-to-differentiate-between-fileprivate-and-private-in-swift),
>>>  on blogs (again, easily googled; as a single example: 
>>> https://useyourloaf.com/blog/swift-3-access-controls/), and messages to 
>>> this list (including from people not part of the original discussion but 
>>> who, on using the feature, found it irksome enough to join the list and 
>>> make their voice heard).
>>> 
>>> You see the new access modifiers described, for example, as something that 
>>> "take[s] some getting used to." Rather damning as a euphemism, don't you 
>>> think? Certainly not a ringing endorsement--
>>> 
>>> "How do you like my new haircut?"
>>> "It, um, takes some getting used to."
>>> 
>>> Others also wrote to say that they were finding it difficult to *teach* 
>>> this new scheme to students; you can find such messages in the list 
>>> archives. I take this to mean that having four/five access modifiers 
>>> (depending on whether you consider `open` to be an access modifier) to be 
>>> one too many.
>>> 
>>> When the Swift core team approved the proposal, they expressed the belief 
>>> that `fileprivate` would be rarely used. This has turned out plainly and 
>>> indisputably not to be true. It is clear that they expected Swift to have, 
>>> after SE-0025 (and before `open`), three commonly used access modifiers and 
>>> one vestigial one. Instead we have four/five commonly used access 
>>> modifiers. Thus, the complexity of the current system is _not_ what was 
>>> envisioned at the time of approval for SE-0025, and the resulting system 
>>> should be re-evaluated in light of this real-world data.
>>> 
>>> So, if four/five access modifiers are too many, which one is carrying the 
>>> least weight? Which one could be removed to simplify the scheme while 
>>> maintaining the most expressiveness? Which one doesn't fulfill even its own 
>>> stated goals? Well, one of the key goals of `private` was to allow members 
>>> to be encapsulated within an extension, hidden even from the type being 
>>> extended (and vice versa for members defined in the type). It says so in 
>>> the first sentence of SE-0025. As seen above in my discussion with Charles 
>>> Srstka, even supporters of `private` disagree with that motivation to begin 
>>> with. The kicker is, _it also doesn't work_. Try, for instance:
>>> 
>>> ```
>>> struct Foo {
>>>   private var bar: Int { return 42 }
>>> }
>>> 
>>> extension Foo {
>>>   private var bar: Int { return 43 }
>>> }
>>> ```
>>> 
>>> The code above should compile and does not. If I understood correctly the 
>>> explanation from a core team member on this list, it's unclear if it can be 
>>> made to work without changing how mangling works, which I believe impacts 
>>> ABI and is not trivial at all. Thus, (a) even proponents of new `private` 
>>> disagree on one of two key goals stated for new `private`; (b) that goal 
>>> was never accomplished, and making it work is not trivial; (c) no one even 
>>> complained about it, suggesting that it was a low-yield goal in the first 
>>> place.
>>> 
>>> So, I conclude that new `private` needs re-evaluation in light of 
>>> real-world implementation and usage experience. I haven't even mentioned 
>>> the nuances of `private` in one scope being different from `private` in the 
>>> containing scope, requiring distinguishing of effective access levels from 
>>> nominal ones--just one more wrinkle in this whole scheme. I feel that 
>>> allowing someone to write `private var foo` instead of `private var _foo // 
>>> don't call this outside the type`, when that member isn't vended and can't 
>>> be seen outside the file anyway, is a tiny win in comparison to the huge 
>>> complexity both of implementation (it's still not correctly implemented and 
>>> may not be in time for Swift 4!!!) and of usage.
>>> 
>>> 
>>>>> On March 21, 2017 at 1:41:48 PM, David Hart (da...@hartbit.com) wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> Sent from my iPhone
>>>>> On 21 Mar 2017, at 16:57, Drew Crawford <d...@sealedabstract.com> 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 (da...@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@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 (dgre...@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-annou...@swift.org 
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
>>>>>>>> 
>>>>>>>> _______________________________________________
>>>>>>>> swift-evolution mailing list
>>>>>>>> swift-evolution@swift.org
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>> 
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to