<div dir="ltr">Thanks for hoisting this out into its own thread, Jordan. I was hesitant to elaborate more on another access level thread :)<div><br></div><div>I think the change should absolutely be made. Even though the "private" keyword occurs at the file level, the description of the feature in the Swift documentation simply states: "you can mark an extension with an explicit access-level modifier to set a new default access level for all members defined within the extension." To me, that implies that "private extension Foo { func bar() }" should be identical to "extension Foo { private func bar() }", but today it becomes equivalent to "extension Foo { fileprivate func bar() }".</div><div><br></div><div>That seems fundamentally broken, because (1) it's inconsistent, (2) "private extension" and "fileprivate extension" are two ways of saying the same thing, non-intuitively, and (3) there's no way for someone to use the shorthand syntax to take advantage of the new meaning of private within same-file type extensions.</div><div><br></div><div>While I personally never use the shorthand extension access level feature (because I prefer the explicit form, and because of situations like this one), I definitely think it should be consistent for people who do want to use it.</div><div><br></div><div>I wonder how much existing code would be affected by this change. Do people use "private extension" when they really want "fileprivate extension"? I would hope the number of users affected would be few, at least.</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Oct 2, 2017 at 6:10 PM Jordan Rose via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><br><div><br><blockquote type="cite"><div>On Oct 2, 2017, at 18:06, Jose Cheyo Jimenez <<a href="mailto:cheyo@masters3d.com" target="_blank">cheyo@masters3d.com</a>> wrote:</div><br class="m_3339905326825804237Apple-interchange-newline"><div><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><br class="m_3339905326825804237Apple-interchange-newline">On Oct 2, 2017, at 5:33 PM, Jordan Rose via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="m_3339905326825804237Apple-interchange-newline"><div><div style="word-wrap:break-word;line-break:after-white-space"><br><div><br><blockquote type="cite"><div>On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="m_3339905326825804237Apple-interchange-newline"><div><div>On 01.10.2017 1:18, Chris Lattner wrote:<br><blockquote type="cite"><blockquote type="cite">On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br><br>Vladimir, I agree with you on that change, but it’s a separate topic from this one.<br><br>Tony is absolutely correct that this topic has already been discussed. It is a deliberate design decision that public types do not automatically expose members without explicit access modifiers; this has been brought up on this list, and it is clearly not in scope for discussion as no new insight can arise this late in the game. The inconsistency with public extensions was brought up, the proposed solution was to remove modifiers for extensions, but this proposal was rejected. So, the final design is what we have.<br></blockquote>Agreed. The core team would only consider a refinement or change to access control if there were something actively broken that mattered for ABI stability.<br></blockquote><br>So we have to live with *protected* extension inconsistency for very long time just because core team don't want to even discuss _this particular_ inconsistency(when access level in *private extension* must be private, not fileprivate)?<br><br>Yes, we decided that access level for extension will mean a default and top most access level for nested methods, OK. But even in this rule, which already differ from access modifiers for types, we have another one special case for 'private extension'.<br><br>Don't you think this is not normal situation and actually there IMO can't be any reason to keep this bug-producing inconsistency in Swift? (especially given Swift 5 seems like is a last moment to fix this)</div></div></blockquote><br></div><div>I hate to say it but I'm inclined to agree with Vladimir on this. "private extension" has a useful meaning now distinct from "fileprivate extension", and it was an oversight that <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md" target="_blank">SE-0169</a> didn't include a fix here. On this<span class="m_3339905326825804237Apple-converted-space"> </span><i>very narrow, very specific<span class="m_3339905326825804237Apple-converted-space"> </span></i>access control issue I think it would still be worth discussing; like Xiaodi said it's not related to James' original thread-starter.</div><div><br></div><div>(I maintain that the current model does<span class="m_3339905326825804237Apple-converted-space"> </span><i>not</i> include a special case; it simply means the 'private' is resolved at the level of the extension rather than the level of its members. But that isn't what people expect and it's not as useful.)</div><div><br></div><div><br></div><div>I agree that changing the behavior of<span class="m_3339905326825804237Apple-converted-space"> </span><i>all</i> access modifiers on extensions is out of scope. (I also agree that it is a bad idea. Sorry, James, but wanting 'pubic' here indicates that your mental model of extensions does not match what Swift is actually doing, and that could get you into trouble.)</div><div><br></div><div>Jordan</div></div></div></blockquote><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">I am not in favor of including a special case for “private extension” because like Jordan said, private is resolved at the level of the extension which is always top level currently. A change would make sense if we start allowing extensions that are not top level. Anything private that is top level is equivalent to fileprivate so why should “private extension” be any different?</div></div></blockquote><br></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div>It's fair to be against this change, but I want to point out that neither of these are "special cases". Instead it's "access is resolved at the level of extension and then applied to the member" vs. "access is applied to the members and then resolved".</div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><br></div><div>Jordan</div><br></div>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>