[swift-evolution] Replace Fileprivate with Hidden + Import Hidden

Xiaodi Wu xiaodi.wu at gmail.com
Sun Oct 16 20:45:07 CDT 2016


No need to rename fileprivate; it's irrelevant to your use case and is
resurrecting a bikeshedding discussion that really needs to be put to rest.

The proposal is essentially for something like @testable for fileprivate
members. Sounds fine to me.
On Mon, Oct 17, 2016 at 09:35 Jonathan Hull via swift-evolution <
swift-evolution at swift.org> wrote:

> On Oct 16, 2016, at 3:28 PM, T.J. Usiyan <griotspeak at gmail.com> wrote:
>
> I don't like this at all and it comes down to  "what is hidden can also
> be unhidden". This, to me, feels like it would create more confusion than
> it would address.
>
> I don’t think it would cause confusion. Other languages have things like
> protected, which is currently a glaring hole in Swift’s access control.
> This addresses that without any of the complexity of friend classes, etc….
>
>
> Why not just use `internal` for `hidden` items?
>
> Because there is an important aspect of communicating the author’s intent.
>
> I think it is important to be able to mark things which are not meant to
> be public (and internal is essentially public in the main module), but may
> be required by extensions/subclasses. With internal, it would be easy to
> accidentally create tightly coupled structures.  With ‘hidden', it requires
> intentional annotation (via the ‘include hidden’ statement) to gain access,
> so more thought will be given to the coupling.
>
> Also, internal would prevent extensions/subclasses outside the defining
> module.  With ‘hidden’ you have an author approved way of extending a type
> (even from another module).  I can’t actually think of a single use of
> ‘fileprivate’ where my intent/need was something other than allowing
> extensions. Unfortunately, with the current model those files can get quite
> a bit bigger than is ideal from an organizational standpoint.
>
>
> If we're ok with modifying import statements, why not simply have a
> command that imports `fileprivate` stuff? (not advocating for this).
>
> From a technical perspective, that is essentially what I am proposing, but
> terminology matters.  The word fileprivate was chosen to convey that the
> associated item was private to scope of the file. With this, we need to
> convey a slightly different intent because, while it does open access at
> file granularity, it is no longer private to the scope of that single file,
> and the name would be misleading.
>
> It doesn’t need to be the word ‘hidden’ necessarily, but it should be
> something with the correct connotation for the new behavior.
>
>
> I think that submodules would have really helped with this issue and it is
> unfortunate that we couldn't get them in for swift 3.
>
> I also want submodules, but they won’t fully solve the protected problem
> above.  They would allow you to group KNOWN subclasses and extensions into
> a single submodule.  But they would also prevent further extensions and
> subclasses from being made by the consumer of that module.  If that is what
> you want, then submodules are the answer, but there are also lots of cases
> where an author wants to allow careful subclassing outside of the original
> module.
>
> A good example of this is UIGestureRecognizer, which separates its
> protected items into a different include.  It hides all of the dangerous
> properties/methods in that separate file, and 98% of the time you don’t
> need it.  However, if you want to create your own gesture recognizer, you
> can’t really do it without those dangerous methods… thus you include the
> file.  With the submodule approach, you would either be unable to create
> your own gesture recognizer subclasses or the dangerous methods would be
> made available inappropriately.
>
>
> Thanks,
> Jon
>
>
> On Sun, Oct 16, 2016 at 4:34 PM, Jonathan Hull via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I keep wanting a “protected” access level, but I must also admit that
> there was something really elegant about Swift 2’s access scheme (and I
> think most of us feel like the word ‘fileprivate’ feels out of place).  I
> was thinking about how to mesh those two ideas, and I think I may have come
> up with a solution.
>
> I propose we replace ‘fileprivate’ with a new ‘hidden’ access level.
> Hidden would work exactly the same way as fileprivate does now, but adds
> the connotation that what is hidden can also be unhidden.  By adding
> ‘import hidden TypeName’ to another file, that file also gains access to
> all of the hidden items of that type (kind of like if it was in the same
> file).
>
> #FileA
>         import Foundation
>
>         Struct A {
>                 private var x:Int
>                 hidden var y:Int  //This is just like fileprivate, but can
> also be shared with other files
>         }
>
>         extension A {
>                 //y can be accessed here because they are in the same file
>         }
>
>
> #FileB
>         import Foundation
>         import hidden A  //This allows the entire file to see A’s hidden
> variables
>
>         extension A {
>                 //y can be accessed here because of the ‘import hidden’
> declaration
>         }
>
>
> #FileC
>         import Foundation
>
>         extension A {
>                 //y can NOT be seen or accessed here because it is hidden
>         }
>
>
> I think this is a fairly elegant solution to our protected dilemma, which
> also feels in sync with Swift 2’s file-based scheme.  The key features:
>         • Extensions no longer need to be piled in the same file if it is
> getting too long
>         • Subclasses can be in their own file, but still have access to
> the necessary parts of their superclass
>         • It communicates the author’s intent that the items are not meant
> to be visible to its users, but that it is expected to be used for
> extension/subclassing
>         • It requires an explicit statement ‘import hidden’ to access the
> hidden variables. Safe by default, with override.
>         • It is not bound by module boundaries  (i.e. you could use it for
> subclassing classes from an imported module)
>         • Roughly the same length as ‘private’ and ‘public’ so various
> declarations packed together are much easier to read (fileprivate breaks
> reading rhythm)
>
> Worth a formal proposal?
>
> Thanks,
> Jon
>
>
>
> _______________________________________________
> 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/20161017/56e6021d/attachment.html>


More information about the swift-evolution mailing list