> On Oct 10, 2017, at 8:24 AM, Vladimir.S <sva...@gmail.com> wrote: > > On 09.10.2017 20:36, Jose Cheyo Jimenez wrote: >>> On Oct 9, 2017, at 9:17 AM, Vladimir.S via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>> >>> On 07.10.2017 20:17, Nevin Brackett-Rozinsky via swift-evolution wrote: >>>> Two weeks ago I had a fairly strong opinion about “private extension” >>>> behavior. After following this discussion, I now have no opinion on the >>>> matter. >>>> I would summarize the points on both sides as follows: >>>> For the change: >>>> • It is surprising to many people that members of a private extension are >>>> implicitly fileprivate. > • There is currently no way to make an extension >>>> whose members default to private. >>> >>> I'd add this: >>> * Current rule for 'private extension' can lead to bugs, when you expect >>> that private methods will be 'true' private but they are fileprivate, so >>> could be called from not-expected code in the same file. Inverse >>> situation(when you need fileprivate but 'private extension' means 'true' >>> private) - can't cause bugs, you'll be notified by the compiler if you need >>> a 'wider' access level. >>> * The change will make the access-control rule for extensions simpler, not >>> harder to understand. >>> * 'fileprivate' access level for methods in extension will be used by >>> *intention*, not just because "this is how 'private extension' works". If I >>> understand correctly, it is not the 'fileprivate' *keyword* we want to see >>> less, but the fileprivate *access level*, which should be rare and >>> intentional. >> Top level private *is* private. Swift did not make a distinction between top >> level private and fileprivate so why should the programmer have to choose? >> If you explicitly declare something private at the top level you are going >> to get fileprivate semantics. This is how scope private works. If you >> disagree then that is a different conversation I think. If you wish for >> these not have an overlap then that is definitely a different proposal? > > I'd like to reply with Xiaodi's words(I hope he will not be against this): > > >---< > The documentation is correct. To interpret it, you must understand that > extensions are not entities and therefore do not have accessibility of their > own; an access modifier in front of “extension” acts only as a shorthand to > set the default and maximum access level of contained members. This aspect of > Swift is not up for change, only the question of what the “private” shorthand > means. > >---< > > i.e. extension is another "thing" than type. You should not derive any > rules/expectation of how access modifiers work for extension based on rules > for type. This could be even(as I showed) dangerous. > > Given the *definition* (and the "spirit", as I undertand it) of how access > modifiers work for extensions, and how this rule *differs* from access > modifiers for type, plus given the potential bugs produced by current rule > for 'private extension' but no problems if one declared 'true' private > extension but needs fileprivate access level, and over-complicated rules for > access modifiers in Swift, and given we can't have a extension of true > private members, especially in the light of new visibility rules for private > members in extensions in the same file - all this leads me to conclusion that > we need to make change. I understand that you have another opinion, but for > me, it is clear that pros of the change are much better than status quo and > than possible cons of the change. > > I.e. I do think current situation is harmful enough to be changed now, and > now is the last chance to fix this for observable future(i.e. after Swift 5). > > As for changing the rules for access modifiers for extensions or their > syntax, as Xiaodi already mentioned, this is out of scope for current > discussion and most likely will not be discussed ever soon.
If the main motivation for changing the rules for `private extension` is because it can lead to bugs, then you can not just dismiss the elephant in the room that is `public extension`. Accidentally leaking a public interface is more damaging than accidentally using an implementation detail. SE-0119 was about completely removing extension modifiers. I am all for fixing the inconsistencies but I do not believe that `private extension` is inconsistent. > > Actually, I feel like we start to repeat the opinions/arguments regarding the > subject, so probably we need to decide if we need a formal proposal. Or > probably we should collect even more opinions on this? Right now I feel like > the most opinions are positive, or I'm wrong? Go for it. I am completely against it but lets see what the community has to say. > > Vladimir. > >>> >>>> Against the change: >>>> • The proposal is source-breaking. >>>> • The proposal makes “fileprivate” more common. >>> >>> It depends on what most of Swift developers *mean* when writing 'private >>> extension' - if they actually need 'fileprivate extension' - then yes, >>> we'll see it more in code. But if in most cases the *intention* is to have >>> a bunch of 'true private' methods - we'll have a small number of >>> 'fileprivate extension'. >>> But in any case, what is the problem with this? If developer *needs* >>> fileprivate access level for methods in extension - this will be clearly >>> stated in code, not hidden under the cute title of 'private extension' >>> >>>> • A private extension and a (top-level) private type both currently have >>>> implicitly fileprivate members. The proposal breaks that symmetry. >>> >>> Is it really good symmetry? >>> By definition, the rule for applying the access level to type is differ >>> from the rule for extension. Here all symmetry already broken and we have 2 >>> separate rules. And from my point of view, having a symmetry in *this >>> particular* case is a bad thing, it can lead to wrong assumptions. Don't >>> you want to apply the same 'symmetry' rule for the code below ? : >> I would be totally on board with making extensions work the same as types. >> So instead of enforcing a default ACL, the extension would work the same way >> as a type by just declaring the upper bound. This would effectively only >> allow extension to lower the upper bound while still making the default ACL >> to internal. This would also be a breaking change for public extensions that >> assume their members to be public. I believe that the behavior of public >> extension is more harmful and more likely to cause bugs because you are >> exposing a public API and may not be aware of it. This would remove the >> ability of open types to be extended with a default ACL of public. The same >> would happen to public types that are being extended with public modifier. >> The below would be symmetrical but now public extension are essentially the >> same as just extension without the modifier. >> open class MyOpenClass {} >> public extension MyOpenClass {// upper bound public >> func myFunc(){}// default internal, upperbound higher it stays internal. >> } >> internal extension MyOpenClass {// upper bound internal >> func myFunc2(){}// default internal >> } >> fileprivate extension MyOpenClass {// upper bound fileprivate >> func myFunc3(){}// default internal but lowered to fileprivate >> } >> private extension MyOpenClass {// upper bound toplevel private >> func myFunc4(){}// default internal but lowered to toplevel private >> } >>> >>> public class C { >>> var i = 10 >>> } >>> >>> public extension C { >>> func j(){} >>> } >>> >>> ,as you understand 'i' is internal, while 'j()' is public. So this could be >>> a dangerous assumption. >>> >>> >>>> Notable questions: >>>> • Currently “open” cannot be applied to an extension at all, should we >>>> allow it? >>> >>> Probably. But this should be a separate pitch/proposal. >>> >>>> • Might we ever want to allow nested (non-top level) extensions, and if so >>>> how should access levels on them work? >>> >>> Not sure if we need them, this is also a subject for separate >>> pitch/proposal. >>> But if the rule for applying the access level for extension will be as >>> currently(I don't believe we'll change it soon) - nested extensions should >>> work the same "the access level keyword stated before the 'extension' >>> keyword will be virtually copy&pasted to the beginning of each method >>> declaration inside extension and then resolved", IMO this is a most clear >>> rule we can have *in case rule for extensions is differ from rule for type”. >> “keyword will be virtually copy&pasted “ sound to me more like extension >> should take a parameter like ‘extension(private)’ or similar. Explicit >> declaration of a keyword should take precedence at the location that it was >> declare. >>> >>> Vladimir. >>> >>>> Nevin >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org <mailto: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