[swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

Xiaodi Wu xiaodi.wu at gmail.com
Tue Oct 10 01:05:15 CDT 2017


On Mon, Oct 9, 2017 at 12:36 Jose Cheyo Jimenez via swift-evolution <
swift-evolution at swift.org> wrote:

> On Oct 9, 2017, at 9:17 AM, Vladimir.S via swift-evolution <
> swift-evolution at 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?
>
>
> 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.
>

This idea was discussed previously and rejected. It’s outside of the narrow
topic here of the meaning of “private extension” specifically.


> 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171010/b1ac73a7/attachment.html>


More information about the swift-evolution mailing list