[swift-evolution] class/struct inner member access scope classifier

Nevin Brackett-Rozinsky nevin.brackettrozinsky at gmail.com
Mon Sep 26 16:03:37 CDT 2016


Just to weigh in here, I too am enjoying Swift 3 greatly.

However, my experience with access modifiers is rather different. I am very
glad that `internal` is the default: this reduces extraneous noise for the
common case, and makes it really easy for new programmers to jump in.

Furthermore, I am beginning to think that changing the meaning of `private`
and introducing `fileprivate` may not have been worth the complexity. Even
with file-scope visibility, one must still use the full path to a member in
order to use it: eg. MyClass.InnerStruct.specialFunction(), so the risk of
collisions is minuscule.

Before the change, the only visibility scopes to consider were file,
module, and everywhere. Now there can be nested private scopes, which may
be “unutterable” in the sense that there is no way to declare a member in
one scope with the same visibility as a private member of an outer scope.

When using the pattern whereby a type is built with many extensions in a
single file, shared helper members must now be declared `fileprivate`
whereas before they were simply `private`. I readily acknowledge that this
is a *small* annoyance, but it is nevertheless that much extra typing and
and that much extra noise.

I don’t expect that reverting such a major change would be worth the
upheaval, especially since many people seem to like it, but I think there
is value in the simpler model that we used to have.

In any event, I *do* think it would be worth renaming “fileprivate” to
something shorter, if a suitable word can be found. I remember how much
bikeshedding went on the first time around, including several people trying
to find a better term than “fileprivate” without any luck, so it may well
turn out that there just isn’t a suitable replacement.

If there is one though, count me on the side in favor of shortening
“fileprivate”.

Nevin



On Mon, Sep 26, 2016 at 3:58 PM, Ted F.A. van Gaalen via swift-evolution <
swift-evolution at swift.org> wrote:

> Hello! Hope you are all OK!
>
> Using and converting To Swift 3.0 with many advantages
> and very little problems.OK, thanks to all !
> also for the reasonably smart converter. Yes, yes, yes, I’m
> still missing the classical for ;; loop (don’t wake me up
> again plse :o)  but overall it is quite good!
>
> I also value the -finally correct- meaning of the scope
> qualifier “private” , thanks,
> which is as it should be (imho) inner scope restricting.
>
> As for “fileprivate”: as yet, I haven’t found a case
> where I should use “fileprivate” also because to me, the contents of
> a file should in principle not have anything to do with the entities
> contained in it, as a file should be just an data carrier. Therefore,
> it should have no effect to wether or not concatenate source.swift files
> into one big file for example, although I would not recommend this.
>
> As far as I can see without binoculars, the “fileprivate” acces modifier
> could be dropped, were it not for source compatibility reasons...
>
> Unless I am missing something:
> Still. something is not quite right yet, I think.
> Just like in a Swift function, I don’t want the inner elements
> of a class (or struct ?) to be visible in outer scope!
> This is the default case in most OOP languages.
> I fail to understand why this is not so in Swift, please enlighten me.
>
> As it is now, and as far as I know, I have to explicitly
> declare *all* entities inside a class that should not be accessible
> outside the class as private, like in this real-world example:
>
>
> class TG3DGauge: SCNNode
> {
>
>
>     private var needles = [SCNNode]()
>     private var fmtStr = “" // private should be the default imho.
>
>
>     var value: CGFloat = 0
>     {
>         didSet  // trigger value change, rotate needles etc.
>         {
>             valueChange()
>         }
>     }
>
>
>     private var nodeUnitText = SCNNode()
>     private var nodeValueText = SCNNode()
>
>
>     private var valRange: ClosedRange<CGFloat> = (0...100.0)
>
>
>     var rangeNeedlesActive: Bool = true
>     {
>         didSet
>         {
>             needles[2].isHidden = !rangeNeedlesActive
>             needles[3].isHidden = !rangeNeedlesActive
>         }
>     }
>
>
>     private var valScaleFactor: CGFloat = 1
>
> // etc. more stuff
> .
>         .
> } // end class TG3DGauge
>
>
> It should (imho) be the other way around: that every member of
> a class is private by default - that is invisible outside the scope
> were it is declared in. This was (and still is) the case with Objective C,
> where you need to explicitly declaring them in  the  sourcefile.h file
> to make them visible and accessible in the outer scope
> Everything else, as existing in the sourcefile.m remains hidden, not
> visible
> in the outer scope.
>
> As a solution/suggestion and also to prevent the gruesome
> horror (did i already wrote something about that?  :o) of source breaking.
> I could think of the “closedscope” (or some other word)
> access modifier, which states that all things declared inside a class,
> are private within the class and thus invisible in the outer scope, unless
> preceeded with an overriding acces scope modifier
> like “public", “internal" or "fileprivate”
>
>
>
> closedscope class TG3DGauge: SCNNode
> {
>
>     var needles = [SCNNode]()  // is now private by default
>     var fmtStr = “"            // is now private by default
>
>
>     public var value: CGFloat = 0 // Public!! visible outside class also
> for “fileprivate" or “internal”
>     {
>         didSet  // trigger value change, rotate needles etc.
>         {
>             valueChange()
>         }
>     }
>
>     var nodeUnitText = SCNNode()  // is now private by default
>     var nodeValueText = SCNNode() // is now private by default
>
>     //etc.
>
>
> This “closedscope" modifier should only be effective for the current
> class, not its superclass(es),
> allowing one to hide/reveal entities in each class independently being
> part of the hierarchy.
> Also entities declared private should not be visible in descendant classes
>
> Also please note that I do miss the “protected” scope access modifier
> which allows entities to be exclusively
> visible to descendant classes, as in Java. Why not implement it in Swift
> as well?
>
> AFAICS:  All mentioned here would not be a source breaking.
>
> Opinions, remarks welcome.
>
> met vriendelijke groeten
> Ted
>
>
>
>
>
>
>
>
>
> _______________________________________________
> 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/20160926/a46be065/attachment.html>


More information about the swift-evolution mailing list