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